ACE_Event_Handler接口是Reactor框架的事件处理器接口,它为应用程序的事件处理提供模板函数。它是框架五元素中的元素2。在示例ACE_TAO 008 Reactor基本原理与说明中,实际上Handle_data类和Acceptor类都是框架五元素中的元素3。ACE_Event_Handler接口的定义如下:

/* -*- C++ -*- *///==========================================================================
/***  @file    Event_Handler.h**  @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>*/
//==========================================================================#ifndef ACE_EVENT_HANDLER_H
#define ACE_EVENT_HANDLER_H
#include /**/ "ace/pre.h"#include /**/ "ace/ACE_export.h"#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */#include "ace/os_include/os_signal.h"
#include "ace/OS_NS_Thread.h"
#include <atomic>ACE_BEGIN_VERSIONED_NAMESPACE_DECL// Forward declaration.
class ACE_Message_Block;
class ACE_Reactor;
class ACE_Reactor_Timer_Interface;
class ACE_Thread_Manager;
class ACE_Process;typedef unsigned long ACE_Reactor_Mask;/*** @class ACE_Event_Handler** @brief* Provides an abstract interface for handling various types of* I/O, timer, and signal events.** Subclasses read/write input/output on an I/O descriptor,* handle an exception raised on an I/O descriptor, handle a* timer's expiration, or handle a signal.*/
class ACE_Export ACE_Event_Handler
{
public:enum{LO_PRIORITY = 0,HI_PRIORITY = 10,NULL_MASK = 0,
#if defined (ACE_USE_POLL)READ_MASK = POLLIN,WRITE_MASK = POLLOUT,EXCEPT_MASK = POLLPRI,
#else /* USE SELECT */READ_MASK = (1 << 0),WRITE_MASK = (1 << 1),EXCEPT_MASK = (1 << 2),
#endif /* ACE_USE_POLL */ACCEPT_MASK = (1 << 3),CONNECT_MASK = (1 << 4),TIMER_MASK = (1 << 5),QOS_MASK = (1 << 6),GROUP_QOS_MASK = (1 << 7),SIGNAL_MASK = (1 << 8),ALL_EVENTS_MASK = READ_MASK |WRITE_MASK |EXCEPT_MASK |ACCEPT_MASK |CONNECT_MASK |TIMER_MASK |QOS_MASK |GROUP_QOS_MASK |SIGNAL_MASK,RWE_MASK = READ_MASK |WRITE_MASK |EXCEPT_MASK,DONT_CALL = (1 << 9)};/// Destructor is virtual to enable proper cleanup.virtual ~ACE_Event_Handler ();/// Get the I/O handle.virtual ACE_HANDLE get_handle () const;/// Set the I/O handle.virtual void set_handle (ACE_HANDLE);// = Get/set priority/// Get the priority of the Event_Handler./// @note Priorities run from MIN_PRIORITY (which is the "lowest priority")/// to MAX_PRIORITY (which is the "highest priority").virtual int priority () const;/// Set the priority of the Event_Handler.virtual void priority (int priority);/// Called when input events occur (e.g., connection or data).virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);/// Called when output events are possible (e.g., when flow control/// abates or non-blocking connection completes).virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);/// Called when an exceptional events occur (e.g., SIGURG).virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE);/*** Called when timer expires.  @a current_time represents the current* time that the Event_Handler was selected for timeout* dispatching and @a act is the asynchronous completion token that* was passed in when <schedule_timer> was invoked.*/virtual int handle_timeout (const ACE_Time_Value &current_time,const void *act = 0);/// Called when a process exits.virtual int handle_exit (ACE_Process *);/// Called when a handle_*() method returns -1 or when the/// remove_handler() method is called on an ACE_Reactor.  The/// @a close_mask indicates which event has triggered the/// handle_close() method callback on a particular @a handle.virtual int handle_close (ACE_HANDLE handle,ACE_Reactor_Mask close_mask);/// Called when object is signaled by OS (either via UNIX signals or/// when a Win32 object becomes signaled).virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);enum{/// The handler is not resumed at all. Could lead to deadlock..ACE_EVENT_HANDLER_NOT_RESUMED = -1,/// The reactor takes responsibility of resuming the handler and/// is the defaultACE_REACTOR_RESUMES_HANDLER = 0,/// The application takes responsibility of resuming the handlerACE_APPLICATION_RESUMES_HANDLER};/*** Called to figure out whether the handler needs to resumed by the* reactor or the application can take care of it. The default* value of 0 would be returned which would allow the reactor to* take care of resumption of the handler. The application can* return a value more than zero and decide to resume the handler* themselves.** @note This method has an affect only when used with the* ACE_Dev_Poll_Reactor (and then, only on Linux) or the ACE_TP_Reactor.*/virtual int resume_handler ();virtual int handle_qos (ACE_HANDLE = ACE_INVALID_HANDLE);virtual int handle_group_qos (ACE_HANDLE = ACE_INVALID_HANDLE);// = Accessors to set/get the various event demultiplexors./// Set the event demultiplexors.virtual void reactor (ACE_Reactor *reactor);/// Get the event demultiplexors.virtual ACE_Reactor *reactor () const;/// Get only the reactor's timer related interface.virtual ACE_Reactor_Timer_Interface *reactor_timer_interface () const;/*** Used to read from non-socket ACE_HANDLEs in our own thread to* work around Win32 limitations that don't allow us to <select> on* non-sockets (such as ACE_STDIN).  This is commonly used in* situations where the Reactor is used to demultiplex read events* on ACE_STDIN on UNIX.  Note that @a event_handler must be a* subclass of ACE_Event_Handler.  If the get_handle() method of* this event handler returns ACE_INVALID_HANDLE we default to* reading from ACE_STDIN.*/static ACE_THR_FUNC_RETURN read_adapter (void *event_handler);/*** Abstracts away from the differences between Win32 and ACE with* respect to reading from ACE_STDIN, which is non-<select>'able on* Win32.*/static int register_stdin_handler (ACE_Event_Handler *eh,ACE_Reactor *reactor,ACE_Thread_Manager *thr_mgr,int flags = THR_DETACHED);/// Performs the inverse of the register_stdin_handler() method.static int remove_stdin_handler (ACE_Reactor *reactor,ACE_Thread_Manager *thr_mgr);/// Reference count type.typedef long Reference_Count;/// Increment reference count on the handler./*** This method is called when the handler is registered with the* Reactor and when the Reactor makes an upcall on the handler.* Reference count is 1 when the handler is created.** @return Current reference count.*/virtual Reference_Count add_reference ();/// Decrement reference count on the handler./*** This method is called when the handler is removed from the* Reactor and when an upcall made on the handler by the Reactor* completes.  Handler is deleted when the reference count reaches* 0.** @return Current reference count.*/virtual Reference_Count remove_reference ();/*** @class Policy** @brief Base class for all handler policies.*/class ACE_Export Policy{public:/// Virtual destructor.virtual ~Policy ();};/*** @class Reference_Counting_Policy** @brief* This policy dictates the reference counting requirements* for the handler.** This policy allows applications to configure whether it wants the* Reactor to call add_reference() and remove_reference() during* registrations, removals, and upcalls.** <B>Default:</B> DISABLED.*/class ACE_Export Reference_Counting_Policy : public Policy{/// This policy can only be created by the handler.friend class ACE_Event_Handler;public:enum Value{/// Perform reference counting.ENABLED,/// Don't perform reference counting.DISABLED};/// Current Reference_Counting_Policy.Value value () const;/// Update Reference_Counting_Policy.void value (Value value);private:/// Private constructor.Reference_Counting_Policy (Value value);/// The value of the policy.Value value_;};/// Current Reference_Counting_Policy.Reference_Counting_Policy &reference_counting_policy ();protected:/// Force ACE_Event_Handler to be an abstract base class.ACE_Event_Handler (ACE_Reactor * = 0,int priority = ACE_Event_Handler::LO_PRIORITY);/// Typedef for implementation of reference counting.typedef std::atomic<Reference_Count> Atomic_Reference_Count;/// Reference count.Atomic_Reference_Count reference_count_;private:/// Priority of this Event_Handler.int priority_;/// Pointer to the various event demultiplexors.ACE_Reactor *reactor_;/// Reference counting requirements.Reference_Counting_Policy reference_counting_policy_;
};/*** @class ACE_Event_Handler_var** @brief Auto pointer like class for Event Handlers.** Used to manage lifecycle of handlers. This class calls* ACE_Event_Handler::remove_reference() in its destructor.*/
class ACE_Export ACE_Event_Handler_var
{
public:/// Default constructor.ACE_Event_Handler_var ();/// Construct with a handler.ACE_Event_Handler_var (ACE_Event_Handler *p);/// Copy constructor.ACE_Event_Handler_var (const ACE_Event_Handler_var &b);/// Destructor.~ACE_Event_Handler_var ();/// Assignment to a handler.ACE_Event_Handler_var &operator= (ACE_Event_Handler *p);/// Assignment to a ACE_Event_Handler_var.ACE_Event_Handler_var &operator= (const ACE_Event_Handler_var &b);/// Overloaded "->".ACE_Event_Handler *operator-> () const;/// Access the handler.ACE_Event_Handler *handler () const;/// Release the handler.ACE_Event_Handler *release ();/// Reset the handler.void reset (ACE_Event_Handler *p = 0);/// Bool operator to check if the ACE_Event_Handler_var has a valueexplicit operator bool() const;/// Equality operator to compare with nullptr_tbool operator ==(std::nullptr_t) const;/// Not equal operator to compare with nullptr_tbool operator !=(std::nullptr_t) const;private:/// Handler.ACE_Event_Handler *ptr_;
};/// Define that we can use in user code to check if this
/// helper factory method is there
#define ACE_HAS_ACE_MAKE_EVENT_HANDLERnamespace ACE
{/// With C++11 it is common to not use C++ new and delete, but/// use std::make_shared and std::make_unique. This will not/// work for ACE event handlers so we introduce a new/// ACE::make_event_handler which can be used in user code to/// allocate a new ACE event handler instance and directly assign/// it to a ACE_Event_Handler_var/// As user this now makes it for example possible to implement/// the following when Simple_Handler is derived from ACE_Event_Handler/// ACE_Event_Handler_var v =///   ACE::make_event_handler<Simple_Handler> (reactor.get());template<class T,typename = typenamestd::enable_if<std::is_base_of<ACE_Event_Handler, T>::value>::type,typename ...Args> inlineACE_Event_Handler_var make_event_handler (Args&& ...args){return ACE_Event_Handler_var (new T (std::forward<Args> (args)...));}
}/*** @class ACE_Notification_Buffer** @brief Simple wrapper for passing ACE_Event_Handler *s and* ACE_Reactor_Masks between threads.*/
class ACE_Export ACE_Notification_Buffer
{
public:ACE_Notification_Buffer ();ACE_Notification_Buffer (ACE_Event_Handler *eh,ACE_Reactor_Mask mask);/// Default destructor.~ACE_Notification_Buffer () = default;/// Pointer to the Event_Handler that will be dispatched/// by the main event loop.ACE_Event_Handler *eh_;/// Mask that indicates which method to call.ACE_Reactor_Mask mask_;
};ACE_END_VERSIONED_NAMESPACE_DECL#include /**/ "ace/post.h"
#endif /* ACE_EVENT_HANDLER_H */

ACE_Event_Handler是一个接口,用于封装Reactor框架支持的IO事件、信号量事件、定时器事件和Notify事件。每一个事件处理器都有一个优先级,用于支持有优先级的事件调度器。事件处理器具有引用计数功能,这是因为同一个事件处理器可以被多次使用,比如一个处理IO的事件处理器可以用作一个定时器。引用计数可以追踪事件处理器的使用计数,当使用计数为0时,框架会删除事件处理器。是否启用引用计数功能,取决于应用程序。在默认情况下,引用计数功能是关闭的,引用计数功能是否开启的属性保存在一个Policy中。

ACE_Event_Handler接口还定义了各类事件的类型和属性,代码如下:

  enum{LO_PRIORITY = 0,HI_PRIORITY = 10,NULL_MASK = 0,
#if defined (ACE_USE_POLL)READ_MASK = POLLIN,WRITE_MASK = POLLOUT,EXCEPT_MASK = POLLPRI,
#else /* USE SELECT */READ_MASK = (1 << 0),WRITE_MASK = (1 << 1),EXCEPT_MASK = (1 << 2),
#endif /* ACE_USE_POLL */ACCEPT_MASK = (1 << 3),CONNECT_MASK = (1 << 4),TIMER_MASK = (1 << 5),QOS_MASK = (1 << 6),GROUP_QOS_MASK = (1 << 7),SIGNAL_MASK = (1 << 8),ALL_EVENTS_MASK = READ_MASK |WRITE_MASK |EXCEPT_MASK |ACCEPT_MASK |CONNECT_MASK |TIMER_MASK |QOS_MASK |GROUP_QOS_MASK |SIGNAL_MASK,RWE_MASK = READ_MASK |WRITE_MASK |EXCEPT_MASK,DONT_CALL = (1 << 9)};

对这些事件的类型和属性的描述,如下表:

LO_PRIORITY 事件低优先级,用于有优先级调度的Reactor管理器
HI_PRIORITY 事件高优先级,用于有优先级调度的Reactor管理器
READ_MASK 读事件
WRITE_MASK 写事件
EXCEPT_MASK 异常事件
ACCEPT_MASK ACCEPT事件
CONNECT_MASK CONNECT事件
TIMER_MASK 定时器事件
QOS_MASK
GROUP_QOS_MASK
SIGNAL_MASK 信号量事件
ALL_EVENTS_MASK 事件组合值,表示所有事件
RWE_MASK 事件组合值,表示分离函数支持的事件
DONT_CALL 指示框架在删除事件处理器时是否调用handle_cloase函数

ACE_Event_Handler接口的主要功能是提供事件处理的模板函数,它们用于处理不同的事件,这些模板函数的功能如下表所示。应用程序可以根据事件的类型实现其中的部分或者全部的处理函数。应用程序只有实现了处理函数,并且把它注册到框架中,框架才能实现调度,框架的Hollywood原则才能得以实现。

处理函数 处理事件
handle_signal 处理信号量事件,当注册的信号发生时,框架会自动调用该处理函数
handle_input 处理IO事件,当注册的描述符有数据输入时,框架会自动调用该函数
handle_exception 处理异常事件
handle_timeout 处理定时器事件
handle_output 处理IO事件,当IO设备的输出队列非满时,框架会自动调用该处理函数

事件处理器接口的使用规范

既然使用Reactor框架,就需要遵守Reactor框架的一些约束。

1。应用程序的事件处理器必须继承ACE_Event_Handler接口,然后注册到框架中,才能被框架调度;

2。ACE_Event_Handler接口的模板函数会被Reactor管理器调用。对于handle_xxx()函数(handle_close除外),框架为它们预设了返回值;小于0,等于0和大于0。

小于0表示处理失败,或者虽然处理成功但需要执行关闭操作。如果使用了DONT_CAIL标志, Reactor处理器在不调用handle_close函数的情况下,将该事件处理器从Reactor管理器中删除;否则Reactor管理器会调用handle_close函数,同时将该事件处理器从Reactor管理器中删除。

等于0表示处理正常,Reactor管理器继续等待事件。

大于0表示在不等待下一个事件的情况下,继续调度事件处理器。

3。Reactor框架建议应用程序使用handle_close而不是delete来释放资源。Reactor框架并不知道用户使用的是动态内存还是静态内存,它只知道在删除事件处理器时,调用handle_close函数,将具体的操作留给应用程序在handle_close中完成,所以handle_close可以用来关闭Socket释放内存等。

4。为了提供更大的灵活性,Reactor框架还在ACE_Event_Handler中使用了引用计数功能。如果应用程序使能了事件处理器的引用计数功能,那么一旦事件处理器的引用计数为0,Reactor管理器会自动删除事件处理器。

多谢,亲爱的美美。

ACE_TAO 014 ACE_Event_Handler相关推荐

  1. ETSI GS MEC 014,UE 标识 API

    目录 文章目录 目录 版本 功能理解 UML UE Identity tag registration UE Identity tag de-registration API Definition U ...

  2. 剑指 Offer II 014. 字符串中的变位词

    剑指 Offer II 014. 字符串中的变位词 题目 示例 解答 题目来源为leetcode 题目 给定两个字符串s1和s2,写一个函数来判断s2是否包含s1的某个变位词. 换句话说,第一个字符串 ...

  3. centos普通用户修改文件权限_Linux实战014:Centos创建用户并添加root授权

    刚收到在腾讯云申请的云服务器8台,现在准备分配给不同项目组来使用.为了确保系统及账号的安全,root账号不能直接给到他们.因为root的权限太大,任何的误操作就可能导致系统异常或者数据丢失找不回来.而 ...

  4. python运维开发培训_运维架构师-Python 自动化运维开发-014

    运维架构师-Python 自动化运维开发-014 九.标准数据类型 1.为什么编程语言中要有类型 类型有以下几个重要角色:对机器而言,类型描述了内存中的电荷是怎么解释的. 对编译器或者解释器而言,类型 ...

  5. win32 014 使用ResEdit 资源编译器 可视化编程 资源的编写

    在rc文件中,各种语句使用的是c语言的格式,因为资源编译器rc.exe根本上就是从visual c++提取出来的 ,学会使用resedit 建立菜单: 3,添加菜单 4,输入  菜单   注意:分隔符 ...

  6. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数014,tuple,元组

    <zw版·Halcon-delphi系列原创教程> Halcon分类函数014,tuple,元组 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号"**&q ...

  7. DecoHack #014 独立产品灵感周刊 - 有些产品很无用但又有很有趣

    本周刊记录有趣好玩的独立产品相关内容,每周发布,欢迎通过 Twitter 私信推荐或投稿. DecoHack #014 独立产品灵感周刊 - 有些产品很无用但又有很有趣 产品推荐 1. Superli ...

  8. 【Matlab身份证识别】身份证号码识别【含GUI源码 014期】

    一.代码运行视频(哔哩哔哩) [Matlab身份证识别]身份证号码识别[含GUI源码 014期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1] 蔡利梅.MAT ...

  9. Intel.VTune.Performance.Analyzer.v8.0.014 分析软件

    为什么80%的码农都做不了架构师?>>>    Intel.VTune.Performance.Analyzer.v8.0.014 分析软件 Introduction_to_Ther ...

最新文章

  1. [学习笔记]最小割之最小点权覆盖最大点权独立集
  2. goroutine 那些事
  3. C语言ODBC方式连接DM数据库
  4. 刚构桥的优缺点_[中交公规院]预应力连续刚构桥总体设计及主要尺寸
  5. c++ list排序_STL之list
  6. Java 多线程执行
  7. 基于ERDAS软件的高分三号(GF-3)SAR影像的预处理
  8. 2022年iFLYTEKA.I.开发者大赛疫情微博情绪识别挑战赛
  9. ISO 14443 非接触式射频卡标准学习
  10. 【来日复制粘贴】提取工作表和工作簿名称
  11. 【电子学会】2020年12月图形化四级 -- 加减法混合运算器
  12. 【tio-websocket】1、T-IO简介
  13. 新概念英语学习的方法
  14. unity聚光灯_聚光灯团队最佳实践:碰撞性能优化
  15. EAV/ESS 8.x 自定义服务器正确方法+更新服务器列表
  16. .mat文件在Matlab中的读取使用操作
  17. 万般皆是命,半点不由人
  18. RTX 4090Ti显卡性能怎么样? RTX 4090Ti功耗
  19. java里单引号怎么打出来_如何在单引号引起来的字符串中转义单引号
  20. Minesweeper by C

热门文章

  1. 微信小程序也许会用到上传视频,针对视频转码转为m3U8格式即web端可以使用的解决办法
  2. C++ 实现哈夫曼树和哈夫曼编码
  3. 小米手机二季度国内业绩回稳微增,雷军组织架构调整成效初显
  4. Windows10系统安装软件后软件界面异常(变得很小或很大),界面显示不完全的解决方案
  5. 百度飞桨领航团python零基础训练营笔记
  6. 论文总结-交通预测(未完成)
  7. 数学建模算法与应用:预测模型(3)案例: SARS 疫情对经济指标影响
  8. iPhone 更新系统后死机怎么搞定?
  9. 【戒焦戒躁,can win】Linux--IO文件描述符
  10. 迅捷路由器设置找不到服务器,迅捷FAST无线路由器设置好了上不了网原因及解决方法...