UC故事2011/11/29
来源:互联网 发布:js视频 编辑:程序博客网 时间:2024/05/16 09:10
1. Reactor
* CRtReactorBase::ScheduleTimer
RtResult CRtReactorBase::
ScheduleTimer(IRtTimerHandler *aTh, LPVOID aArg,
const CRtTimeValue &aInterval, DWORD aCount)
{
m_Est.EnsureSingleThread();
if (!m_pTimerQueue) {
RT_WARNING_TRACE("CRtReactorBase::ScheduleTimer, m_pTimerQueue not inited or closed.");
return RT_ERROR_NOT_INITIALIZED;
}
return m_pTimerQueue->ScheduleTimer(aTh, aArg, aInterval, aCount);
// Q,设计上说,Reactor既本身是一种TimerQueue,同时又含有一种TimerQueue实例,Why?
}
* CRtReactorBase的纯虚函数
virtual void OnHandleRemoved(RT_HANDLE aFd) = 0;
virtual RtResult OnHandleRegister(
RT_HANDLE aFd,
IRtEventHandler::MASK aMask,
IRtEventHandler *aEh) = 0;
注:这两个方法需要子类提供,以处理真正register/remove handle的情况。
Q:但这个register/remove handle与EventHandler Repository之间什么关系?
* CRtReactorWin32AsyncSelect:::OnHandleRegister
RtResult CRtReactorWin32AsyncSelect::
OnHandleRegister(RT_HANDLE aFd, IRtEventHandler::MASK aMask, IRtEventHandler *aEh)
{
return DoAsyncSelect_i(aFd, IRtEventHandler::ALL_EVENTS_MASK);
}
注:在这个OnHandler中,真正完成的事是调用WSAASyncSelect将socket与windows handler绑定,从而使得当出现网络相关的Windows Message时,相关Message Handler会被调用。
RtResult CRtReactorWin32AsyncSelect::
DoAsyncSelect_i(RT_HANDLE aFd, IRtEventHandler::MASK aMask)
{
long lEvent = 0;
if (aMask & IRtEventHandler::CONNECT_MASK)
lEvent |= FD_CONNECT;
......
if (::WSAAsyncSelect((SOCKET)aFd, m_hwndNotify, WM_WIN32_SOCKET_SELECT, lEvent) != 0) {
RT_ERROR_TRACE_THIS("CRtReactorWin32AsyncSelect::DoAsyncSelect_i, WSAAsyncSelect() failed!"
" aFd=" << aFd <<
" err=" << ::WSAGetLastError());
return RT_ERROR_UNEXPECTED;
}
else
return RT_OK;
}
STACK TRACE:
CRtReactorWin32AsyncSelect::OnHandleRegister(void * 0x00000674, long 2, IRtEventHandler * 0x020ab300) line 343
CRtReactorBase::RegisterHandler(IRtEventHandler * 0x020ab300, long 2) line 219 + 31 bytes
CRtConnectorTcpT<CRtConnectorWrapper,CRtTransportTcp,CRtSocketStream>::Connect_i(CRtTransportTcp * 0x020ab688, const CRtInetAddr & {...}) line 202 + 25 bytes
CRtConnectorTcpT<CRtConnectorWrapper,CRtTransportTcp,CRtSocketStream>::Connect(const CRtInetAddr & {...}, CRtInetAddr * 0x00000000) line 82 + 22 bytes
CRtConnectorWrapper::AsycConnect(IRtAcceptorConnectorSink * 0x020ab548, const CRtInetAddr & {...}, CRtTimeValue * 0x020ad41c, CRtInetAddr * 0x00000000) line 109 + 26 bytes
CConnConnectorT<CRtConnRlbTcpClient>::AsycConnect(IRtAcceptorConnectorSink * 0x020ad074, const CRtInetAddr & {...}, CRtTimeValue * 0x020ad41c, CRtInetAddr * 0x00000000) line 357 + 84 bytes
CEventAsycConnect::OnEventFire() line 187 + 74 bytes
CRtEventQueueBase::ProcessOneEvent(IRtEvent * 0x020ad3f0) line 229 + 12 bytes
CRtEventQueueBase::ProcessEvents(const std::list<IRtEvent *,std::allocator<IRtEvent *> > & {...}) line 217
CRtReactorBase::ProcessHandleEvent(void * 0xffffffff, long 256, int 0, int 1, int 0) line 324 + 18 bytes
CRtReactorWin32Message::Win32SocketWndProc(HWND__ * 0x000508cc, unsigned int 1058, unsigned int 4294967295, long 256) line 115
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d196c7()
CRtReactorWin32Message::RunEventLoop() line 262 + 15 bytes
CRtThreadReactor::OnThreadRun() line 67 + 19 bytes
CRtThread::ThreadProc(void * 0x020a7ef0) line 151 + 13 bytes
_threadstartex(void * 0x020a7fa0) line 227 + 13 bytes
KERNEL32! 7c80b729()
Q:如何解读?
2. Thread
* CRtThread
class RT_API_EXPORT CRtThread
{
public:
....
/virtual RtResult Create(
CRtThreadManager::TType aType,
CRtThreadManager::TFlag aFlag = CRtThreadManager::TF_JOINABLE);
// Stop thread so that let the thread function return.
virtual RtResult Stop(CRtTimeValue* aTimeout = NULL);
// Wait until the thread function return.
RtResult Join(DWORD aMilliseconds = RT_INFINITE);
virtual void OnThreadInit();
virtual void OnThreadRun() = 0; // 唯一pure virtual function,一个操作系统线程执行的代码实体
virtual IRtReactor* GetReactor(); // for what ? reactor , eventqueue and timerqueue ? what's for ?
virtual IRtEventQueue* GetEventQueue();
virtual IRtTimerQueue* GetTimerQueue();
...
private:
...
static unsigned WINAPI ThreadProc(void *aPara); // 启动一个新线程用的函数.
...
private:
CRtEventThread *m_pEvent4Start; // For what ? @brief A wrapper around the Win32 event locking mechanism ?
BOOL m_bRegistered;
...
};
* thread相关属性:分别的业务含义?
typedef int TType;
enum
{
TT_MAIN,
TT_NETWORK,
TT_DNS,
TT_CURRENT,
TT_TIMER,
TT_UNKNOWN = -1,
// This private thread type is used by applications.
TT_USER_DEFINE_BASE = 1000
};
enum TFlag
{
TF_NONE = 0,
TF_JOINABLE = (1 << 0),
TF_DETACHED =
* 理解Thread的启动与执行
for win32:
a) _beginThreadex
unsigned long __cdecl _beginthreadex (
void *security,
unsigned stacksize,
unsigned (__stdcall * initialcode) (void *),
void * argument, // 此为传给子线程线程函数的参数,对应于上一个参数的void *
unsigned createflag,
unsigned *thrdaddr
)
b) 启动新线程:CRtThread::Create() {
m_Handle = (HANDLE)::_beginthreadex(
NULL,
0,
ThreadProc,
this, // 这里就是本线程实例自身,-这样,在线程函数里能调用Thread Instance里定义的方法,而最重要的是OnThreadRun(),这是线程的执行代码循环。
0,
(unsigned int *)(&m_Tid));
}
c) CRtThread::ThreadProc
static unsigned WINAPI ThreadProc(void *aPara); // 线程对象本身作为参数传入
ThreadProc(...)
{
CRtThread *pThread = static_cast<CRtThread *>(aPara); // 取得线程对象指针
pThread->OnThreadInit(); // 执行线程对象OnThreadInit(),本函数执行后,才会进入下一步,主线程才有机会被唤醒。
if (pThread->m_Type != CRtThreadManager::TT_MAIN) { // 如果非主线程,则唤醒主线程
...
if (pThread->m_pEvent4Start)
pThread->m_pEvent4Start->Signal(); // 唤醒主线程:signal
}
pThread->OnThreadRun(); // 执行线程代码实体,实际上是执行Reactor::RunEventLoop(),对于Windows而言就是Message Loop
......
return NULL;
}
3. Reactor and Thread
void CRtThreadReactor::OnThreadRun()
{
...
m_pReactor->RunEventLoop(); // 调用Reactor的事件处理循环
m_pReactor->Close(); // 关闭Reactor事件处理循环
...
}
注:所以,一个操作系统线程运行的实际代码就是Reactor的事件循环。
RtResult CRtReactorWin32Message::RunEventLoop()
{
RT_INFO_TRACE_THIS("CRtReactorWin32Message::RunEventLoop");
m_Est.EnsureSingleThread();
MSG msg;
while (!CRtStopFlag::m_bStoppedFlag && ::GetMessage(&msg, NULL, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return RT_OK;
}
注:Windows下的事件处理就是Windows的消息处理过程。Linux下有另外的机制,但抽象意义上说是RunEventLoop。
- UC故事2011/11/29
- UC故事 2010-11-29
- UC故事 2011-04-11
- UC故事2011/10/11
- UC故事 2011/11/15
- UC故事 2011/11/16
- UC故事2011/11/17
- UC故事2011/11/18
- UC故事2011/11/19
- UC故事 2011/11/21
- UC故事2011/11/22
- UC故事 2011/11/24
- UC故事2011/11/25
- UC故事2011/11/26
- UC故事2011/11/28
- UC故事2011/11/30
- UC故事2011/11/20 - 1
- UC故事 2011/11/20 - 2
- unix用户的配置文件 .bash_profile和.bashrc
- 字符编码笔记:ASCII,Unicode和UTF-8
- AJAX请求时status返回状态明细表 readyState的五种状态
- 在python 2.7平台下访问mysql 5.0数据库
- 环球邮报解读华为:中国企业要征服世界
- UC故事2011/11/29
- 解决vs03 安装中可恶的FrontPage 2000 WEB
- 算法入门--计数排序
- ORACLE的analyze使用简介 (转载)
- 使用 FileNet Content API 开发以内容为核心的流程
- 自学PHP的笔记(七)小例子两头
- Error #2044: 未处理的 AsyncErrorEvent
- 使用LinkedList实现Queue
- text-decoration:line-through;删除线相对字不在中间