mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 17:30:53 +08:00
367 lines
13 KiB
C
367 lines
13 KiB
C
#ifndef ACL_EVENTS_H_INCLUDED
|
||
#define ACL_EVENTS_H_INCLUDED
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
#include "../stdlib/acl_define.h"
|
||
#include <time.h>
|
||
#include "../stdlib/acl_vstream.h"
|
||
#include "acl_timer.h"
|
||
|
||
/*+++++++++++++++++++++++++++ 全局宏定义 +++++++++++++++++++++++++++++++++++*/
|
||
/* Event codes. */
|
||
#define ACL_EVENT_READ (1 << 0) /**< read event */
|
||
#define ACL_EVENT_ACCEPT (1 << 1) /**< accept one connection */
|
||
#define ACL_EVENT_WRITE (1 << 2) /**< write event */
|
||
#define ACL_EVENT_CONNECT (1 << 3) /**< client has connected the server*/
|
||
#define ACL_EVENT_XCPT (1 << 4) /**< exception */
|
||
#define ACL_EVENT_TIME (1 << 5) /**< timer event */
|
||
#define ACL_EVENT_RW_TIMEOUT (1 << 6) /**< read/write timeout event */
|
||
#define ACL_EVENT_TIMEOUT ACL_EVENT_RW_TIMEOUT
|
||
|
||
#define ACL_EVENT_FD_IDLE 0
|
||
#define ACL_EVENT_FD_BUSY 1
|
||
|
||
#define ACL_EVENT_ERROR ACL_EVENT_XCPT
|
||
|
||
#define ACL_EVENT_SELECT 0
|
||
#define ACL_EVENT_POLL 1
|
||
#define ACL_EVENT_KERNEL 2
|
||
#define ACL_EVENT_WMSG 3
|
||
|
||
/*
|
||
* Dummies.
|
||
*/
|
||
#define ACL_EVENT_NULL_TYPE 0
|
||
#define ACL_EVENT_NULL_CONTEXT ((char *) 0)
|
||
|
||
|
||
/* in acl_events.c */
|
||
|
||
typedef struct ACL_EVENT ACL_EVENT;
|
||
typedef struct ACL_EVENT_FDTABLE ACL_EVENT_FDTABLE;
|
||
|
||
/*
|
||
* External interface.
|
||
*/
|
||
#if 0
|
||
typedef void (*ACL_EVENT_NOTIFY_FN) (int event_type, void *context);
|
||
typedef ACL_EVENT_NOTIFY_FN ACL_EVENT_NOTIFY_RDWR;
|
||
typedef ACL_EVENT_NOTIFY_FN ACL_EVENT_NOTIFY_TIME;
|
||
#else
|
||
typedef void (*ACL_EVENT_NOTIFY_RDWR)(int event_type, ACL_EVENT *event,
|
||
ACL_VSTREAM *stream, void *context);
|
||
typedef void (*ACL_EVENT_NOTIFY_TIME)(int event_type, ACL_EVENT *event,
|
||
void *context);
|
||
#endif
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* 创建一个事件循环对象的总入口,此函数会根据用户参数的不同自动调用下面的事件对象创建函数
|
||
* @param event_mode {int} 事件处理方式,目前仅支持: ACL_EVENT_SELECT, ACL_EVENT_KERNEL,
|
||
* ACL_EVENT_POLL, ACL_EVENT_WMSG
|
||
* @param use_thr {int} 是否采用线程事件方式,非0表示按线程事件方式
|
||
* @param delay_sec {int} 事件循环等待时的最长秒数,当 event_mode 为 ACL_EVENT_WMSG
|
||
* 时,且该值大于 0 时,则该值被当作消息值对待传给 acl_event_new_wmsg,用来与异
|
||
* 步消息句柄绑定
|
||
* @param delay_usec {int} 事件循环等待时的最长微秒数(仅 select 方式有用)
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new(int event_mode, int use_thr,
|
||
int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个新的事件对象, 该事件不支持多线程
|
||
* @param delay_sec {int} 在调用 select() 函数时休息的秒数
|
||
* @param delay_usec {int} 在调用 select() 函数时休息的微秒数
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_select(int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个新的事件对象, 该事件支持线程模式
|
||
* @param delay_sec {int} 在调用 select() 函数时休息的秒数
|
||
* @param delay_usec {int} 在调用 select() 函数时休息的微秒数
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_select_thr(int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个支持 poll 的事件对象,不支持多线程
|
||
* @param delay_sec {int} 在调用 poll() 函数时休息的秒数
|
||
* @param delay_usec {int} 在调用 poll() 函数时休息的微秒数
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_poll(int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个支持 poll 的事件对象,支持多线程
|
||
* @param delay_sec {int} 在调用 poll() 函数时休息的秒数
|
||
* @param delay_usec {int} 在调用 poll() 函数时休息的微秒数
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_poll_thr(int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个新的事件对象, 该事件采用效率高的 epoll/devpoll/kqueue 方式,且不支持多线程
|
||
* @param delay_sec {int} 在调用事件循环函数时休息的秒数
|
||
* @param delay_usec {int} 在调用事件循环函数时休息的微秒数(忽略不计)
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_kernel(int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个新的事件对象, 该事件采用效率高的 epoll/devpoll/kqueue 方式,且采用线程方式
|
||
* @param delay_sec {int} 在调用事件循环函数时休息的秒数
|
||
* @param delay_usec {int} 在调用事件循环函数时休息的微秒数(忽略不计)
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_kernel_thr(int delay_sec, int delay_usec);
|
||
|
||
/**
|
||
* 创建一个能与 Windows 界面消息绑在一起的事件引擎对象
|
||
* @param nMsg {unsigned int} 如果该值大于 0 则将该异步句柄与该消息值绑定,
|
||
* 否则将该异步句柄与缺省的消息值绑定
|
||
* @return {ACL_EVENT*} 事件对象指针,如果为空表示出错
|
||
*/
|
||
ACL_API ACL_EVENT *acl_event_new_wmsg(unsigned int nMsg);
|
||
|
||
#if defined (_WIN32) || defined(_WIN64)
|
||
ACL_API HWND acl_event_wmsg_hwnd(ACL_EVENT *eventp);
|
||
#endif
|
||
|
||
/**
|
||
* 为了防止在多线程模式下 select 等事件循环的时间等待,可以添加此项以中断等待,
|
||
* 加快事件循环过程
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
*/
|
||
ACL_API void acl_event_add_dog(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 设置事件触发的前置和后置处理过程
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param fire_begin {void (*)(ACL_EVENT*, void*)} 当事件被统一触发前的回调过程
|
||
* @param fire_end {void (*)(ACL_EVENT*, void*)} 当事件被统一触发后的回调过程
|
||
* @param ctx {void*} fire_begin / fire_end 的第二个参数
|
||
*/
|
||
ACL_API void acl_event_set_fire_hook(ACL_EVENT *eventp,
|
||
void (*fire_begin)(ACL_EVENT*, void*),
|
||
void (*fire_end)(ACL_EVENT*, void*),
|
||
void* ctx);
|
||
|
||
/**
|
||
* 设置事件循环过程中定时检查所有描述字状态的时间间隔,内部缺省值为 100 ms
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param n {int} 定时查检时间间隔 (毫秒级)
|
||
*/
|
||
ACL_API void acl_event_set_check_inter(ACL_EVENT *eventp, int n);
|
||
|
||
/**
|
||
* 释放事件结构
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
*/
|
||
ACL_API void acl_event_free(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 返回事件的时间截
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @return {acl_int64} 当前事件的时间截(微秒级别)
|
||
*/
|
||
ACL_API acl_int64 acl_event_time(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 将事件中的所有任务执行完毕
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
*/
|
||
ACL_API void acl_event_drain(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 设置数据流可读时(指有数据待读或描述符出错或描述符关闭)的回调函数
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
* @param read_timeout {int} 读超时时间(秒)
|
||
* @param callback {ACL_EVENT_NOTIFY_RDWR} 数据流可读时的回调函数
|
||
* @param context {void*} 回调函数 callback 所需要的参数
|
||
*/
|
||
ACL_API void acl_event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
|
||
int read_timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context);
|
||
|
||
/**
|
||
* 设置数据流可写时(指有空间可以写或描述符出错或描述符关闭)的回调函数
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
* @param write_timeout {int} 写超时时间(秒)
|
||
* @param callback {ACL_EVENT_NOTIFY_RDWR} 数据流可写时的回调函数
|
||
* @param context {void*} 回调函数 callback 所需要的参数
|
||
*/
|
||
ACL_API void acl_event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream,
|
||
int write_timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context);
|
||
|
||
/**
|
||
* 设置监听套接口(指有新连接到达/被系统中断/出错时)的回调函数
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
* @param read_timeout {int} 监听超时时间(秒),可以为0
|
||
* @param callback {ACL_EVENT_NOTIFY_RDWR} 数据流可读时的回调函数
|
||
* @param context {void*} 回调函数 callback 所需要的参数
|
||
*/
|
||
ACL_API void acl_event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream,
|
||
int read_timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context);
|
||
|
||
/**
|
||
* 将数据流从事件的读监听流集合中清除
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API void acl_event_disable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 将数据流从事件的写监听流集合中清除
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API void acl_event_disable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 将数据流从事件的读写监听流集合中清除
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API void acl_event_disable_readwrite(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 检查流中的描述符是否已经置入读、写或异常事件的集合中
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API int acl_event_isset(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 检查流中的描述符是否已经置入读事件的集合中
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API int acl_event_isrset(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 检查流中的描述符是否已经置入写事件的集合中
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API int acl_event_iswset(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 检查流中的描述符是否已经置入异常事件的集合中
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param stream {ACL_VSTREAM*} 数据流指针, 不能为空, 且其中的描述符必须是有效的
|
||
*/
|
||
ACL_API int acl_event_isxset(ACL_EVENT *eventp, ACL_VSTREAM *stream);
|
||
|
||
/**
|
||
* 添加一个定时事件
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param callback {ACL_EVENT_NOTIFY_TIME} 定时事件的回调函数
|
||
* @param context {void*} callback 所需要的回调参数
|
||
* @param delay {acl_int64} eventp->event_present + delay 为该事件函数开始执行的时间
|
||
* 单位为微秒
|
||
* @param keep {int} 是否重复定时器任务
|
||
* @return {acl_int64} 事件执行的时间截,单位为微秒
|
||
*/
|
||
ACL_API acl_int64 acl_event_request_timer(ACL_EVENT *eventp,
|
||
ACL_EVENT_NOTIFY_TIME callback, void *context, acl_int64 delay, int keep);
|
||
|
||
/**
|
||
* 取消一个定时事件
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param callback {ACL_EVENT_NOTIFY_TIME} 定时事件的回调函数
|
||
* @param context {void*} callback 所需要的回调参数
|
||
* @return acl_int64 {acl_int64} 距离开始执行事件函数的时间间隔, 以微秒为单位
|
||
*/
|
||
ACL_API acl_int64 acl_event_cancel_timer(ACL_EVENT *eventp,
|
||
ACL_EVENT_NOTIFY_TIME callback, void *context);
|
||
|
||
/**
|
||
* 当定时器处理完毕后,是否需要再次设置该定时器,以方便调用者循环
|
||
* 使用该定时器
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param callback {ACL_EVENT_NOTIFY_TIME} 非空
|
||
* @param context {void*} 附属于 callback 的变量
|
||
* @param onoff {int} 是否重复通过 acl_event_request_timer 设置的定时器
|
||
*/
|
||
ACL_API void acl_event_keep_timer(ACL_EVENT *eventp, ACL_EVENT_NOTIFY_TIME callback,
|
||
void *context, int onoff);
|
||
|
||
/**
|
||
* 判断所设置的定时器都处于重复使用状态
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param callback {ACL_EVENT_NOTIFY_TIME} 非空
|
||
* @param context {void*} 附属于 callback 的变量
|
||
* @return {int} !0 表示所设置的定时器都处于重复使用状态
|
||
*/
|
||
ACL_API int acl_event_timer_ifkeep(ACL_EVENT *eventp, ACL_EVENT_NOTIFY_TIME callback,
|
||
void *context);
|
||
|
||
/**
|
||
* 事件循环执行的调度函数
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
*/
|
||
ACL_API void acl_event_loop(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 设置事件循环的空闲休息时间中的秒级数值
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param sec {int} 秒级空闲休息时间值
|
||
*/
|
||
ACL_API void acl_event_set_delay_sec(ACL_EVENT *eventp, int sec);
|
||
|
||
/**
|
||
* 设置事件循环的空闲休息时间中的微秒级数值
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @param usec {int} 微秒级空闲休息时间值
|
||
*/
|
||
ACL_API void acl_event_set_delay_usec(ACL_EVENT *eventp, int usec);
|
||
|
||
/**
|
||
* 获得事件循环的空闲休息时间中的秒级数值
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @return {int} 秒级空闲休息时间值
|
||
*/
|
||
ACL_API int acl_event_get_delay_sec(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 获得事件循环的空闲休息时间中的微秒级数值
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @return {int} 微秒级空闲休息时间值
|
||
*/
|
||
ACL_API int acl_event_get_delay_usec(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 是否采用线程事件方式
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @return {int} 0: 否; !=0: 是
|
||
*/
|
||
ACL_API int acl_event_use_thread(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 获得当前事件引擎的事件模型
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @return {int} ACL_EVENT_SELECT/ACL_EVENT_KERNEL/ACL_EVENT_POLL
|
||
*/
|
||
ACL_API int acl_event_mode(ACL_EVENT *eventp);
|
||
|
||
/**
|
||
* 获得本次事件循环后被触发的 IO 事件的次数
|
||
* @param eventp {ACL_EVENT*} 事件对象指针, 不为能为空
|
||
* @return {int} 该值为本次循环被触发的事件次数
|
||
*/
|
||
ACL_API int acl_event_last_nready(ACL_EVENT *eventp);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif
|