[ACE源码分析]ACE_Reactor是如何做到事件分发的
转载自:http://www.cppblog.com/sandy/archive/2006/02/23/3451.html
1. ACE_Reactor的创建
ACE_Reactor: ACE_Reactor (ACE_Reactor_Impl *implementation = 0,int delete_implementation = 0);
你可以自己创建一个ACE_Reactor
但是大多数时候,我们都是通过调用ACE_Reactor::instance()这个静态方法来返回唯一的实例。
2. Impl手法的运用
ACE_Reactor有个成员变量 ACE_Reactor_Impl *implementation_;
这个implementation_才是真正做事情的东西,典型的Impl手法。
为什么要多一个这个间隔层呢,主要是为了实现跨平台。
因为不同的平台的Reactor差异很大。
在Windows平台,实现这个是ACE_WFMO_Reactor
classACE_ExportACE_WFMO_Reactor: publicACE_Reactor_Impl
ACE_Reactor: ACE_Reactor (ACE_Reactor_Impl *implementation = 0,int delete_implementation = 0);
你可以自己创建一个ACE_Reactor
但是大多数时候,我们都是通过调用ACE_Reactor::instance()这个静态方法来返回唯一的实例。
ACE_Reactor*
ACE_Reactor::instance( void)
{
ACE_TRACE("ACE_Reactor::instance");
if(ACE_Reactor::reactor_==0) //1
{
// PerformDouble-CheckedLockingOptimization.
ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,ace_mon,
*ACE_Static_Object_Lock::instance(),0));
if(ACE_Reactor::reactor_==0) //2
{
ACE_NEW_RETURN(ACE_Reactor::reactor_,
ACE_Reactor,
0);
ACE_Reactor::delete_reactor_=1;
ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor,ACE_Reactor::reactor_)
}
}
returnACE_Reactor::reactor_;
}
注意这点使用了双检测的机制(代码1和2),为了提高效率,不用每次都加锁。
ACE_Reactor::instance( void)
{
ACE_TRACE("ACE_Reactor::instance");
if(ACE_Reactor::reactor_==0) //1
{
// PerformDouble-CheckedLockingOptimization.
ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,ace_mon,
*ACE_Static_Object_Lock::instance(),0));
if(ACE_Reactor::reactor_==0) //2
{
ACE_NEW_RETURN(ACE_Reactor::reactor_,
ACE_Reactor,
0);
ACE_Reactor::delete_reactor_=1;
ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor,ACE_Reactor::reactor_)
}
}
returnACE_Reactor::reactor_;
}
2. Impl手法的运用
ACE_Reactor有个成员变量 ACE_Reactor_Impl *implementation_;
这个implementation_才是真正做事情的东西,典型的Impl手法。
为什么要多一个这个间隔层呢,主要是为了实现跨平台。
因为不同的平台的Reactor差异很大。
在Windows平台,实现这个是ACE_WFMO_Reactor
classACE_ExportACE_WFMO_Reactor: publicACE_Reactor_Impl
3. Event_Handle的管理
ACE_WFMO_Reactor把要管理的Handle都放在 ACE_WFMO_Reactor_Handler_Repository handler_rep_;
这里要注意的是io_handle和event_handle的区别
io_handle是真正的handle,比如socket_handle,thread_handle
而event_handle是绑定在io_handle上面的事件handle
有代码为证:
1 int
2ACE_WFMO_Reactor::register_handler_i(ACE_HANDLEevent_handle,
3ACE_HANDLEio_handle,128)">4ACE_Event_Handler*event_handler,128)">5ACE_Reactor_Masknew_masks)
6{
7 IfthisisaWinsock1system,theunderlyingeventassignmentwill
8 notwork,sodon'ttry.Winsock1mustuseACE_Select_Reactorfor
9 reactingtosocketactivity.
10
11 Makesurethatthe<handle>isvalid 12 if(io_handle==ACE_INVALID_HANDLE)
13io_handle=event_handler->get_handle();
14
15 if( this->handler_rep_.invalid_handle(io_handle))
16{
17errno=ERROR_INVALID_HANDLE;
18 return-1;
19}
20
21 longnew_network_events=0;
22 intdelete_event=0;
23auto_ptr<ACE_Auto_Event> event;
24
25 Lookuptherepositorytoseeifthe<event_handler>isalready
26 there. 27 ACE_Reactor_Maskold_masks;
28 intfound= this->handler_rep_.modify_network_events_i(io_handle,128)">29new_masks,128)">30old_masks,128)">31new_network_events,128)">32event_handle,128)">33delete_event,128)">34ACE_Reactor::ADD_MASK);
35
36 Checktoseeiftheuserpassedusavalidevent;Ifnotthenwe
37 needtocreateone 38 if(event_handle==ACE_INVALID_HANDLE)
39{
40 Note:don'tchangethissincesomeC++compilershave
41 <auto_ptr>sthatdon'tworkproperly 42 auto_ptr<ACE_Auto_Event>tmp( newACE_Auto_Event);
43 event=tmp;
44event_handle= event->handle();
45delete_event=1;
46}
47
48 intresult=::WSAEventSelect((SOCKET)io_handle,128)">49event_handle,128)">50new_network_events);