ACE_Select_Reactor的Notify功能实现浅析

前端之家收集整理的这篇文章主要介绍了ACE_Select_Reactor的Notify功能实现浅析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

ACE_Select_Reactor的@H_502_3@Notify功能实现浅析@H_502_3@

作者@H_502_3@ : ydogg @H_502_3@ 如需转载@H_502_3@ ,@H_502_3@ 请注明@H_502_3@ .@H_502_3@ @H_502_3@
1. @H_502_3@@H_502_3@@H_502_3@ 前言
本文关注平台@H_502_3@为Win32,但在其它的@H_502_3@类Unix 平台,就@H_502_3@实现 框架而言并没有@H_502_3@太多变 化@H_502_3@ ,惟一不同的是用于底@H_502_3@层 机制的@H_502_3@ACE_Pipe 的@H_502_3@实现
@H_502_3@ 但是,为了解决某些特别的原因,如大量的通知存储、规避悬空处理器指针等,@H_502_3@ ACE@H_502_3@ 也提供了一种有别于@H_502_3@ Pipe@H_502_3@ 解决方案,其采用消息排队的方式工作。当采取这种方式时,需定义@H_502_3@ ACE_HAS_REACTOR_NOTIFICATION_QUEUE@H_502_3@ 宏并重生成@H_502_3@ ACE@H_502_3@ 。@H_502_3@ @H_502_3@

2. @H_502_3@@H_502_3@@H_502_3@ Notify@H_502_3@的@H_502_3@能力、@H_502_3@风险@H_502_3@和风险@H_502_3@规@H_502_3@避@H_502_3@ @H_502_3@

Notify@H_502_3@ 机制最重要的能力是:
1. @H_502_3@@H_502_3@@H_502_3@ 让反应器拥有了处理无限处理器的能力
2. @H_502_3@@H_502_3@@H_502_3@ 其次是提供了必要时解除反应器事件检查阻塞的能力。@H_502_3@ @H_502_3@

Reactor@H_502_3@的@H_502_3@notify()@H_502_3@用户直接提供给@H_502_3@Reactor@H_502_3@通知反应器的指针,而这些处理器无需注册到反应器上,从而提供了无限的扩展能力。但是,在使用@H_502_3@ACE_Pipe@H_502_3@的实现中,如果使用不当,可能会造成严重的后果。
@H_502_3@

潜在的风险:
1. @H_502_3@@H_502_3@@H_502_3@ 处理器被销毁后,排队等候的对应通知才被分派
2. @H_502_3@@H_502_3@@H_502_3@ ACE_Pipe@H_502_3@的数据缓冲是有限的,大量通知到来可能会造成阻塞甚至死锁@H_502_3@ @H_502_3@

因为通知的信息(包括处理器指针和掩码)以流数据的方式被写入@H_502_3@ACE_Pipe@H_502_3@,不能进行遍历查找,所以当对应处理器被销毁后,如果其在@H_502_3@CE_Pipe@H_502_3@的数据区中还有存储有通知,则@H_502_3@ACE_Reactor@H_502_3@将会在分派中使用悬空指针,造成未知的后果。另外,在@H_502_3@ACE_Pipe@H_502_3@的数据缓冲已满情况下,在处理器的回调中依然发送通知,就会因阻塞发生死锁。@H_502_3@ @H_502_3@

在采用@H_502_3@ACE_Pipe@H_502_3@的@H_502_3@Notify@H_502_3@实现中,以上两个问题的规避只能依靠用户自己的应用机制。@H_502_3@ @H_502_3@

不过,在采用队列的@H_502_3@Notify实现@H_502_3@中,@H_502_3@ACE@H_502_3@ 给提供了问题的解决方法
1. @H_502_3@@H_502_3@@H_502_3@ 采用队列方式可无限扩展@H_502_3@Notify@H_502_3@ 数量
2. @H_502_3@@H_502_3@@H_502_3@ 采用队列方式为通知查询提供的方便,因此@H_502_3@ACE_Reactor@H_502_3@提供@H_502_3@puerge_pending_notifications()@H_502_3@方法来移除指定的通知,当处理器销毁时,可以使用该方法移除当前队列中所有和自己相关的通知,避免了使用悬空指针。
@H_502_3@

在采用@H_502_3@ACE_Pipe@H_502_3@方式中,@H_502_3@puerge_pending_notifications()@H_502_3@被实现为空方法。@H_502_3@ @H_502_3@


@H_502_3@
3. @H_502_3@@H_502_3@@H_502_3@ ACE_Select_Reactor类图
可以看出,@H_502_3@ACE_Select_Reactor_T 是具体的@H_502_3@实现负责 者。@H_502_3@

@H_502_3@

4. @H_502_3@@H_502_3@@H_502_3@ 参与Notify机制的类
参与@H_502_3@Notify 机制的@H_502_3@类 有:@H_502_3@
ACE_Select_Reactor_Impl 、@H_502_3@ACE_Select_Reactor_Notify 和@H_502_3@ACE_Pipe 。从@H_502_3@ACE_Select_Reactor 开始,采用自上而向下的@H_502_3@顺 序@H_502_3@进 行分析。@H_502_3@
@H_502_3@
5. @H_502_3@@H_502_3@@H_502_3@ 实现原理
各@H_502_3@类 型@H_502_3@Reactor 的@H_502_3@实现 方法有所不同,比如@H_502_3@Select_Reactor 是通@H_502_3@过 管道来@H_502_3@实现notify 功能,而@H_502_3@WFMO则 通@H_502_3@过ACE_Event类 型@H_502_3@ 的的事件加通知队列来@H_502_3@实现 。@H_502_3@
Reactor 在初始化@H_502_3@时 ,会@H_502_3@创 建@H_502_3@ 一个@H_502_3@pipe 。然后将@H_502_3@该pipe 的句柄注册到@H_502_3@Reactor 。@H_502_3@这样 ,@H_502_3@这 个@H_502_3@Pipe 就@H_502_3@处 于@H_502_3@Reactor 的事件分派句柄集中,像其他普通句柄一@H_502_3@样 ,被@H_502_3@Reactor 所@H_502_3@监测 和分派。当@H_502_3@用户用@H_502_3@notify()时 ,@H_502_3@notify() 会把参数信息写入@H_502_3@这 个@H_502_3@ 管道,通过事件监测,从而@H_502_3@Reactor 就能得知有新@H_502_3@notify 到来,从管道@H_502_3@读 取@H_502_3@ 相关数据后,就可以@H_502_3@进 行@H_502_3@ 相@H_502_3@应 的分派@H_502_3@处 理@H_502_3@ 。从而@H_502_3@实现 通知和事件分派的序列化。@H_502_3@
详细 的来@H_502_3@说 ,@H_502_3@ACE为 所有的@H_502_3@Reactor 都定@H_502_3@义 了@H_502_3@专为 它@H_502_3@们 自己服@H_502_3@务 的@H_502_3@Notify类 ,如@H_502_3@
ACE_Select_Reactor_Notify 和@H_502_3@ACE_WFO_Reactor_Notify 。@H_502_3@
在@H_502_3@类Unix 平台上,支持管道并且@H_502_3@select 可用于@H_502_3@监测 管道事件。但是在@H_502_3@Win32 平台并不支持管道功能,而且@H_502_3@Winsock 的@H_502_3@select 只能支持@H_502_3@对socket 句柄的事件@H_502_3@监测 。因此,@H_502_3@ACE 在@H_502_3@Win32 平台用一个本地@H_502_3@连 接@H_502_3@ 来模@H_502_3@拟Pipe 功能,其中接受@H_502_3@连 接@H_502_3@ 的@H_502_3@socket 句柄作@H_502_3@为Pipe读 句柄,而@H_502_3@发 起@H_502_3@连 接@H_502_3@ 的@H_502_3@socket 句柄作@H_502_3@为Pipe 的写句柄。@H_502_3@
可以看出,@H_502_3@notify 功能的@H_502_3@实现机制类似于ACE_Reactor 的@H_502_3@标 准@H_502_3@ 用法,@H_502_3@并 且也有一个@H_502_3@类 似于@H_502_3@ACE_Event_Handler 的@H_502_3@类 存在,只不@H_502_3@过 是被包含在@H_502_3@Reactor 中。在@H_502_3@逻辑 意@H_502_3@义 上,就是一个本地@H_502_3@连 接@H_502_3@ ,用于和@H_502_3@进 程@H_502_3@ 内的其他部分的通信@H_502_3@ @H_502_3@(略有差别的地方在于事件分派的方式) 。@H_502_3@
于@H_502_3@ACE_Select_Reactor,ACE_Pipe 充当了@H_502_3@ACE_Sock_Stream 的角色,而@H_502_3@ACE_Select_Reactor_Notify则 充当了@H_502_3@ACE_Event_Handler 的角色。@H_502_3@ACE_Select_Reactor_Notify 派生自@H_502_3@ACE_Reactor_Notify,而@H_502_3@ACE_Reactor_Notify 正是派生自@H_502_3@ACE_Event_Handler.

6. @H_502_3@@H_502_3@@H_502_3@ 相关变量
ACE_Select_Reactor_Impl类 中,定@H_502_3@义 了@H_502_3@类 型@H_502_3@为ACE_Reactor_Notify* 的成@H_502_3@员变
@H_502_3@
/@H_502_3@ CallbackobjectthatunblockstheACE_Select_Reactorifit's
@H_502_3@ ///@H_502_3@ sleeping.@H_502_3@
@H_502_3@ ACE_Reactor_Notify@H_502_3@ *@H_502_3@ notify_handler_;@H_502_3@

@H_502_3@@H_502_3@

7. @H_502_3@@H_502_3@@H_502_3@实现分析

7.1 @H_502_3@@H_502_3@ 初始化@H_502_3@
ACE_Select_Reactor_T 的@H_502_3@open 函数定@H_502_3@义 如下:
@H_502_3@ virtual@H_502_3@ int@H_502_3@ open(size_tmax_number_of_handles@H_502_3@ =@H_502_3@ DEFAULT_SIZE,
@H_502_3@ restart@H_502_3@ 0@H_502_3@ ,
ACE_Sig_Handler@H_502_3@ *@H_502_3@ 502_3@ disable_notify_pipe@H_502_3@ ACE_DISABLE_NOTIFY_PIPE_DEFAULT,
ACE_Reactor_Notify@H_502_3@ );@H_502_3@

@H_502_3@

其中@H_502_3@ACE_DISABLE_NOTIFY_PIPE_DEFAULT@H_502_3@的@H_502_3@值为@H_502_3@0,@H_502_3@表示默@H_502_3@认@H_502_3@要使用@H_502_3@Notify@H_502_3@功能。@H_502_3@
这@H_502_3@个@H_502_3@值@H_502_3@会@H_502_3@传递给@H_502_3@ACE_Select_Reactor_Notify@H_502_3@的构造函数。@H_502_3@在@H_502_3@open()@H_502_3@的@H_502_3@实现@H_502_3@中:@H_502_3@

@H_502_3@ if@H_502_3@ (result@H_502_3@ !=@H_502_3@ -@H_502_3@ 1@H_502_3@ &&@H_502_3@ this@H_502_3@ ->@H_502_3@ notify_handler_@H_502_3@ ==@H_502_3@ 0@H_502_3@ )
@H_502_3@

如果没有使用外部的@H_502_3@notify@H_502_3@时@H_502_3@,@H_502_3@ACE_Select_Reactor_T@H_502_3@将会@H_502_3@让@H_502_3@notify_handler@H_502_3@指向一个@H_502_3@new@H_502_3@出来的@H_502_3@ACE_Select_Reactor_Notify@H_502_3@类@H_502_3@型的@H_502_3@对@H_502_3@象,并@H_502_3@调@H_502_3@用它的@H_502_3@open()@H_502_3@方法@H_502_3@进@H_502_3@行初始化。@H_502_3@
@H_502_3@

ACE_Select_Reactor_Notify@H_502_3@的@H_502_3@open()@H_502_3@实现@H_502_3@如下(@H_502_3@删@H_502_3@除@H_502_3@了非关@H_502_3@键@H_502_3@代@H_502_3@码@H_502_3@):@H_502_3@

(disable_notify_pipe@H_502_3@ )
{
@H_502_3@ select_reactor_@H_502_3@
dynamic_cast@H_502_3@ <@H_502_3@ ACE_Select_Reactor_Impl@H_502_3@ *>@H_502_3@ (r);

@H_502_3@ (select_reactor_@H_502_3@ )
{
errno@H_502_3@ EINVAL;
@H_502_3@ return@H_502_3@ ;
}

@H_502_3@ notification_pipe_.open()@H_502_3@ )
@H_502_3@ ;

@H_502_3@ (ACE::set_flags(@H_502_3@ notification_pipe_.read_handle(),
ACE_NONBLOCK)@H_502_3@
@H_502_3@ register_handler
(@H_502_3@ 502_3@
{
@H_502_3@ ;
}@H_502_3@

@H_502_3@

注意,@H_502_3@这@H_502_3@里的@H_502_3@disable_notify_pipe@H_502_3@就是@H_502_3@ACE_Select_Reactor_T@H_502_3@的@H_502_3@open()@H_502_3@方法中@H_502_3@传递@H_502_3@的参数,通@H_502_3@过@H_502_3@它,可以@H_502_3@设@H_502_3@置不使用@H_502_3@notify@H_502_3@功能
可以看出,@H_502_3@ACE_Select_Reactor_Notify@H_502_3@的@H_502_3@open()@H_502_3@的主要功能是初始化自己的@H_502_3@ACE_Pipe@H_502_3@类@H_502_3@型成@H_502_3@员对@H_502_3@象@H_502_3@notification_pipe_@H_502_3@,并把它注册到@H_502_3@Reactor@H_502_3@中,@H_502_3@监测@H_502_3@read@H_502_3@事件。@H_502_3@
@H_502_3@

ACE_Pipe@H_502_3@的@H_502_3@open()@H_502_3@实现@H_502_3@如下(@H_502_3@Win32@H_502_3@平台并@H_502_3@删@H_502_3@除了非关@H_502_3@键@H_502_3@代@H_502_3@码@H_502_3@):@H_502_3@

ACE_INET_Addrmy_addr;
ACE_SOCK_Acceptoracceptor;
ACE_SOCK_Connectorconnector;
ACE_SOCK_Streamreader;
ACE_SOCK_Streamwriter;
@H_502_3@ int@H_502_3@ result@H_502_3@ ;
#@H_502_3@ defined(ACE_WIN32)
ACE_INET_Addrlocal_any(static_cast@H_502_3@ u_short@H_502_3@ >@H_502_3@ #endif@H_502_3@
@H_502_3@ (acceptor.open(local_any)@H_502_3@ ||@H_502_3@ acceptor.get_local_addr(my_addr)@H_502_3@
@H_502_3@

可以看到,@H_502_3@ ACE_Pipe@H_502_3@ 通@H_502_3@ 过@H_502_3@ 了一个自身的@H_502_3@ Tcp@H_502_3@ 连@H_502_3@ 接来模@H_502_3@ 拟@H_502_3@ Pipe@H_502_3@ ,@H_502_3@ 读@H_502_3@ 写句柄分@H_502_3@ 别@H_502_3@ 就是两端的@H_502_3@ socket@H_502_3@ 句柄,很巧妙的@H_502_3@ Pipe@H_502_3@ 移植。@H_502_3@ 而@H_502_3@ ACE_Pipe@H_502_3@ 的@H_502_3@ read_handle@H_502_3@ ()@H_502_3@ 函数返回的是@H_502_3@ handles_@H_502_3@ [@H_502_3@ 0@H_502_3@ ]@H_502_3@ ,也就是说,注册到@H_502_3@ Reactor@H_502_3@ 是读@H_502_3@ socket,@H_502_3@ 而@H_502_3@ handles_@H_502_3@ [1]@H_502_3@ 将会被@H_502_3@ 客户所使用。@H_502_3@ @H_502_3@

7.2 @H_502_3@@H_502_3@@H_502_3@方法调@H_502_3@用@H_502_3@ @H_502_3@

在@H_502_3@用@H_502_3@户@H_502_3@使用@H_502_3@notify@H_502_3@相关方法@H_502_3@时@H_502_3@,@H_502_3@ACE_Select_Reactor_T@H_502_3@充当中介,会将@H_502_3@将它@H_502_3@们@H_502_3@直接交由内部的@H_502_3@notify_handler@H_502_3@对象@H_502_3@处@H_502_3@理。@H_502_3@
ACE_Select_Reactor_T@H_502_3@的@H_502_3@notify()@H_502_3@代码:@H_502_3@ @H_502_3@

ssize_t@H_502_3@ const@H_502_3@ n@H_502_3@ notify(eh,mask,imeout);
@H_502_3@ ?@H_502_3@ :@H_502_3@ ;
@H_502_3@

ACE_Select_Reactor_Nofity@H_502_3@的@H_502_3@notify()@H_502_3@函数代码:@H_502_3@ @H_502_3@

;

ACE_Event_Handler_varsafe_handler(event_handler);

@H_502_3@ (event_handler)
event_handler@H_502_3@ add_reference();

ACE_Notification_Bufferbuffer(event_handler,mask);
ssize_t@H_502_3@ ACE::send(@H_502_3@ notification_pipe_.write_handle(),
(@H_502_3@ char@H_502_3@ *@H_502_3@ )@H_502_3@ &@H_502_3@ buffer,255);">sizeof@H_502_3@ 502_3@ (n@H_502_3@ //@H_502_3@ Nofailures.@H_502_3@ safe_handler.release();@H_502_3@

这@H_502_3@段@H_502_3@代@H_502_3@码@H_502_3@将用@H_502_3@户传递@H_502_3@的“目的@H_502_3@Handler@H_502_3@指@H_502_3@针@H_502_3@“和”掩@H_502_3@码@H_502_3@“参数,@H_502_3@写入了@H_502_3@”@H_502_3@管道@H_502_3@,实则是通过@H_502_3@socket@H_502_3@句柄发送了数据。@H_502_3@A@H_502_3@CE_Notification_Buffer@H_502_3@是一个简单的数据包裹类。@H_502_3@ @H_502_3@

7.3 @H_502_3@@H_502_3@@H_502_3@事件分派@H_502_3@ @H_502_3@

Reactor()@H_502_3@的@H_502_3@事件多路分离@H_502_3@流程:@H_502_3@
ACE_Reactor::@H_502_3@run_reactor_event_loop@H_502_3@() -> ACE_Select_Reactor_T::@H_502_3@handle_events@H_502_3@() ->
ACE_Select_Reactor_T::@H_502_3@handle_events_i@H_502_3@() @H_502_3@

ACE_Select_Reactor_T::@H_502_3@()@H_502_3@代码如下:@H_502_3@ @H_502_3@

ACE_SEH_TRY
{
@H_502_3@ Weusethedatamemberdispatch_set_asthecurrentdispatch
@H_502_3@ set.
@H_502_3@ Weneedtostartfromacleandispatch_set@H_502_3@ dispatch_set_.rd_mask_.reset();
@H_502_3@ dispatch_set_.wr_mask_.reset();
@H_502_3@ dispatch_set_.ex_mask_.reset();

@H_502_3@ number_of_active_handles@H_502_3@ wait_for_multiple_events(@H_502_3@ dispatch_set_,
max_wait_time);

result@H_502_3@ dispatch(number_of_active_handles,0);">dispatch_set_);
}
ACE_SEH_EXCEPT(@H_502_3@ release_token())
{

}
@H_502_3@

Reactor@H_502_3@在监测事件时,不区分@H_502_3@Noftiy@H_502_3@用句柄和其它句柄,一视同仁。所以无需关心@H_502_3@wait_for_multiple_events@H_502_3@的实现。@H_502_3@
ACE_Select_Reactor_T::@H_502_3@ dispatch@H_502_3@ @H_502_3@的关键代码如下:@H_502_3@dispatch_timer_handlers(other_handlers_dispatched)@H_502_3@ StatehaschangedortimerqueuehasFailed,exitloop.@H_502_3@ break@H_502_3@ dispatch_notification_handlers
(dispatch_set,
active_handle_count,
other_handlers_dispatched)@H_502_3@ StatehaschangedoraserIoUsfailurehasoccured,soexit
@H_502_3@ loop.@H_502_3@ dispatch_io_handlers
(dispatch_set,
io_handlers_dispatched)@H_502_3@ Statehaschanged,soexitloop.@H_502_3@ ;
@H_502_3@


可以看出,@H_502_3@Select_Reactor@H_502_3@分派事件时是按照:定时器、通知、@H_502_3@IO@H_502_3@事件的顺序进行的。
这里也许有人会疑惑,为什么不直接将notify的处理放在io的分派函数@H_502_3@dispatch_io_handlers()中处理呢? 这个想法合情合理,但是Select_Reactor中,规定notify事件的优先级要比普通IO事件的优先级高,以便可以处理一些优先级较高的突发事件。@H_502_3@所以必须在@H_502_3@IO@H_502_3@事件分派前,主动的分派@H_502_3@n@H_502_3@otify@H_502_3@事件。并且@H_502_3@在@H_502_3@notify@H_502_3@事件分派后,需要将@H_502_3@Pipe@H_502_3@的句柄从@H_502_3@dispatch_set@H_502_3@去除,以免在@H_502_3@事件分派中被重复分派。@H_502_3@ @H_502_3@

@H_502_3@
dispatch_notification_handlers@H_502_3@代码:@H_502_3@dispatch_notifications(number_of_active_handles,
dispatch_set.rd_mask_);

@H_502_3@
{
number_of_handlers_dispatched@H_502_3@ +=@H_502_3@ n;
number_of_active_handles@H_502_3@ -=@H_502_3@ n;
}
@H_502_3@


ACE_Select_Reactor_T::@H_502_3@dispatch_notifications@H_502_3@函数代码:@H_502_3@ACE_HANDLE@H_502_3@ read_handle@H_502_3@ notification_pipe_.read_handle();

@H_502_3@ (read_handle@H_502_3@ ACE_INVALID_HANDLE
@H_502_3@ rd_mask.is_set(read_handle))
@H_502_3@

到了这里,@H_502_3@handle_input@H_502_3@出现了,下面的处理和@H_502_3@ACE_Event_Handler@H_502_3@相近了。@H_502_3@
ACE_Select_Reactor_Notify::handle_input()@H_502_3@函数代码:@H_502_3@

number_dispatched@H_502_3@ ;
ACE_Notification_Bufferbuffer;

@H_502_3@ while@H_502_3@ ((result@H_502_3@ read_notify_pipe(handle,buffer))@H_502_3@ dispatch_notify(buffer)@H_502_3@ ++@H_502_3@ number_dispatched;

@H_502_3@ (number_dispatched@H_502_3@ max_notify_iterations_)
@H_502_3@ ;
}
@H_502_3@

代码逻辑很清楚,从@H_502_3@Pipe@H_502_3@的缓冲区中依次读取所有接受到的@H_502_3@Notify@H_502_3@事件信息,并且交给@H_502_3@dispatch_notify@H_502_3@去处理,如果达到设定值@H_502_3@max_notify_iterations_@H_502_3@(ACE_Reactor::@H_502_3@ max_notify_iterations@H_502_3@函数功能@H_502_3@)@H_502_3@,就停止分派。@H_502_3@

@H_502_3@需要注意:由于是依次从@H_502_3@Pipe@H_502_3@中读取信息,如果在用户指定的@H_502_3@Notify@H_502_3@处理@H_502_3@Handler@H_502_3@调用@H_502_3@notify()(@H_502_3@嵌套使用@H_502_3@,给@H_502_3@在此写入信息,就容易造成@H_502_3@Reactor@H_502_3@的死循环。@H_502_3@
在@H_502_3@WFMO_Reactor@H_502_3@的对应实现中,因为使用@H_502_3@Event,@H_502_3@所以对应的函数是@H_502_3@handle_signal(). @H_502_3@

ACE_Select_Reactor_Notify::@H_502_3@dispatch_notify@H_502_3@ @H_502_3@

(buffer.eh_@H_502_3@ )
{
ACE_Event_Handler@H_502_3@ event_handler@H_502_3@ buffer.eh_;

@H_502_3@ bool@H_502_3@ requires_reference_counting@H_502_3@
event_handler@H_502_3@ reference_counting_policy().value()@H_502_3@
ACE_Event_Handler::Reference_Counting_Policy::ENABLED;

@H_502_3@ switch@H_502_3@ (buffer.mask_)
{
@H_502_3@ case@H_502_3@ ACE_Event_Handler::READ_MASK:
@H_502_3@ ACE_Event_Handler::ACCEPT_MASK:
result@H_502_3@ handle_input(ACE_INVALID_HANDLE);
@H_502_3@ ACE_Event_Handler::WRITE_MASK:
result@H_502_3@ handle_output(ACE_INVALID_HANDLE);
@H_502_3@ ACE_Event_Handler::EXCEPT_MASK:
result@H_502_3@ handle_exception(ACE_INVALID_HANDLE);
@H_502_3@ ACE_Event_Handler::QOS_MASK:
result@H_502_3@ handle_qos(ACE_INVALID_HANDLE);
@H_502_3@ ACE_Event_Handler::GROUP_QOS_MASK:
result@H_502_3@ handle_group_qos(ACE_INVALID_HANDLE);
@H_502_3@ default@H_502_3@ :
@H_502_3@ Shouldwebailoutifwegetaninvalidmask?@H_502_3@ ACE_ERROR((LM_ERROR,
ACE_TEXT(@H_502_3@ "@H_502_3@ invalidmask=%d @H_502_3@ 502_3@ )
event_handler@H_502_3@ handle_close(ACE_INVALID_HANDLE,
ACE_Event_Handler::EXCEPT_MASK);
}
@H_502_3@
@H_502_3@ @H_502_3@

这里是分派的终点,用户传递的用于处理@H_502_3@Notify@H_502_3@事件的@H_502_3@Handler@H_502_3@根据@H_502_3@mask@H_502_3@的类型而被调用。@H_502_3@

8.序列图

猜你在找的React相关文章