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。

 

 

 

原创粉丝点击