sloop公共函数之添加信号,定时器及socket
1:添加信号
1.1 原型:sloop_handle sloop_register_signal(int sig, sloop_signal_handler handler, void * param)
/* register a signal handler */
sloop_handle sloop_register_signal(int sig, sloop_signal_handler handler, void * param)
{
struct sloop_signal * entry;
struct sigaction sa; sa.sa_handler = sloop_signals_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART; /* allocate a new structure sloop_signal */
entry = get_signal();
if (entry == NULL)
return NULL; /* setup structure and insert into list. */
entry->sig = sig;
entry->param = param;
entry->handler = handler;
dlist_add(&entry->list, &sloop.signals);
SLOOPDBG(d_dbg("sloop: sloop_register_signal(%d)\n", sig));
if (sigaction(sig, &sa, NULL) < ) {
dlist_del(&entry->list);
free_signal(entry);
d_error("sigaction %d error %s\n", sig, strerror(errno));
return NULL;
} return entry;
}
这个函数提供给使用sloop模块的第三方,只需要传入要监听的信号、信号处理函数、参数,就可以将此信号登记到sloop_data结构体中的struct dlist_head signals链表中,在sloop_run函数中进行监听。get_signal函数是从初始化时的struct dlist_head free_signals链表中取出一个可用的节点挂在struct dlist_head signals链表中。具体实现如下:
/* get signal from pool */
static struct sloop_signal * get_signal(void)
{
struct dlist_head * entry;
struct sloop_signal * target; if (dlist_empty(&sloop.free_signals)) {
d_error("sloop: no sloop_signal available !!!\n");
return NULL;
}
entry = sloop.free_signals.next;
dlist_del(entry);
target = dlist_entry(entry, struct sloop_signal, list);
target->flags = SLOOP_INUSED | SLOOP_TYPE_SIGNAL;
return target;
}
flags参数主要是为了标识此节点的类型,有三种类型,SLOOP_TYPE_SOCKET、SLOOP_TYPE_TIMEOUT、SLOOP_TYPE_SIGNAL。
1.2 一般使用方法
sloop_register_signal(SIGTERM, sig_term, NULL);登记SIGTERM信号的处理函数是sig_term,没有要传递的参数。
2:添加定时器
2.1 原型:sloop_handle sloop_register_timeout(unsigned int secs, unsigned int usecs, sloop_timeout_handler handler, void * param)
同添加信号的实现思路是一样的,需要传递的参数是定时器的秒和微妙参数。
/* register a timer */
sloop_handle sloop_register_timeout(unsigned int secs, unsigned int usecs, sloop_timeout_handler handler, void * param)
{
struct sloop_timeout * timeout, * tmp;
struct dlist_head * entry; /* allocate a new struct sloop_timeout. */
timeout = get_timeout();
if (timeout == NULL) return NULL; /* get current time */
gettimeofday(&timeout->time, NULL);
timeout->time.tv_sec += secs;
timeout->time.tv_usec += usecs; while (timeout->time.tv_usec >= ) {
timeout->time.tv_sec++;
timeout->time.tv_usec -= ;
}
timeout->handler = handler;
timeout->param = param;
INIT_DLIST_HEAD(&timeout->list); /* put into the list */
if (dlist_empty(&sloop.timeout)) {
dlist_add(&timeout->list, &sloop.timeout);
SLOOPDBG(d_dbg("sloop: timeout(0x%x) added !\n", timeout));
return timeout;
} entry = sloop.timeout.next;
while (entry != &sloop.timeout) {
tmp = dlist_entry(entry, struct sloop_timeout, list);
if (timercmp(&timeout->time, &tmp->time, < )) break;
entry = entry->next;
}
dlist_add_tail(&timeout->list, entry);
SLOOPDBG(d_dbg("sloop: timeout(0x%x) added !!\n", timeout));
return timeout;
}
2.2 一般使用方法
sloop_register_timeout(1, 0, wan_handler, param);在登记之后的1秒执行函数wan_handler。
3:添加套接字
3.1 原型:套接字分为监听可读或可写两种
/* register a read socket */
sloop_handle sloop_register_read_sock(int sock, sloop_socket_handler handler, void * param)
{
return register_socket(sock, handler, param, &sloop.readers);
} /* register a write socket */
sloop_handle sloop_register_write_sock(int sock, sloop_socket_handler handler, void * param)
{
return register_socket(sock, handler, param, &sloop.writers);
}
分别挂载到sloop.readers和sloop.writers链表上。
static struct sloop_socket * register_socket(int sock,
sloop_socket_handler handler, void * param, struct dlist_head * head)
{
struct sloop_socket * entry; /* allocate a new structure sloop_socket */
entry = get_socket();
if (entry == NULL) return NULL; /* setup structure and insert into list. */
entry->sock = sock;
entry->param = param;
entry->handler = handler;
dlist_add(&entry->list, head);
SLOOPDBG(d_dbg("sloop: new socket : 0x%x (fd=%d)\n", (unsigned int)entry, entry->sock));
return entry;
}
get_socket实现:
/* get socket from pool */
static struct sloop_socket * get_socket(void)
{
struct dlist_head * entry;
struct sloop_socket * target; if (dlist_empty(&sloop.free_sockets)) {
d_error("sloop: no sloop_socket available !!!\n");
return NULL;
}
entry = sloop.free_sockets.next;
SLOOPDBG(daig_printf("%s: get socket sd=[%x],\n", __FILE__, entry));
dlist_del(entry);
target = dlist_entry(entry, struct sloop_socket, list);
target->flags = SLOOP_INUSED | SLOOP_TYPE_SOCKET;
return target;
}
综上:
这就是这四种功能的实现思路及使用方式。
sloop公共函数之添加信号,定时器及socket的更多相关文章
- sloop公共程序之初始过程及启动
1:sloop_init() 初始化主要是初始化静态sloop_*** 结构体和填充struct sloop_data 结构体中的成员. //初始化静态存储区给sloop_***结构体 static ...
- 除了信号触发线程与接收者线程相同的情况能直接调用到slot,其它情况都依赖事件机制(解决上面代码收不到信号的问题其实很简单,在线程的run();函数中添加一个事件循环就可以了,即加入一句exec();),信号槽不就是一个回调函数嘛
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { pThreadCon = new CSerialThread ...
- sloop公共程序之总体描述
1:功能需求 开发一个公共库文件sloop.c,实现三个常用功能以供其它模块调用.三个功能如下: 功能一:实现一般的信号监听,调用模块只需传入要监听的信号和相应的回调函数就可以在信号到时调用回调函数处 ...
- 在Qt Creator 和在 vs2012 里添加信号和槽
原文地址:http://www.cnblogs.com/li-peng/p/3644812.html 作者:李鹏 出处:http://www.cnblogs.com/li-peng/ 本文版权归作者和 ...
- Postman高级应用——流程控制、调试、公共函数、外部数据文件
postman客户端下载地址:https://www.getpostman.com/apps 目录 流程控制 调试 公共函数 外部数据文件 流程控制 流程控制简言之就是设置接口的执行顺序,流程控制只有 ...
- VS2005 添加onTimer定时器
SetTimer(1,300,NULL); void CchangeDisplayDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调 ...
- phpcms公共函数库 总结
* global.func.php 公共函数库 /** * 返回经addslashes处理过的字符串或数组 * @param $string 需要处理的字符串或数组 * @return mixed ...
- cmf公共函数解析
cmf公共函数解析-common.php 路径:thinkcmf\simplewind\cmf\common.php方法: 方法 作用 返回值 cmf_get_current_admin_id ...
- ThinkPHP 3.2.3 自动加载公共函数文件的方法
方法一.加载默认的公共函数文件 在 ThinkPHP 3.2.3 中,默认的公共函数文件位于公共模块 ./Application/Common 下,访问所有的模块之前都会首先加载公共模块下面的配置文件 ...
随机推荐
- Delphi 中的 RectTracker - 原创
本文算是副产品,正品是利用 FFmpeg 从任意视频中生成GIF片段的小程序,写完了就发. V2G 正品已出炉,虽然不大像样,但好歹是能用,请见:用 Delphi 7 实现基于 FFMS2 的视频转 ...
- [转载]文件系统缓存dirty_ratio与dirty_background_ra
原文地址:文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别作者:vincent 这两天在调优数据库性能的过程中需要降低操作系统文件Cache对数据库性能的影 ...
- kafka可靠性
文章转载自: http://blog.csdn.net/u013256816/article/details/71091774
- LeetCode 888. Fair Candy Swap(C++)
题目: Alice and Bob have candy bars of different sizes: A[i] is the size of the i-th bar of candy that ...
- Alpha发布—文案+美工展示
目录 团队简介 项目进展 组内分工 队员总结 后期计划 一.团队简介 二.项目进展 从选题发布到今天的Alpha发布,我们团队经历了许许多多的磨难.我们最终设计了如下的功能:首页.班级.个人.更多.打 ...
- ios程序后台继续运行
1.图标右上角显示消息个数 if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { UIUserNotificati ...
- HDU 5465 Clarke and puzzle Nim游戏+二维树状数组
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 26 ...
- Objective-C Json转Model(利用Runtime特性)
封装initWithNSDictionary:方法 该方法接收NSDictionary对象, 返回PersonModel对象. #pragma mark - 使用runtime将JSON转成Model ...
- Linux系统中增加swap空间大小
在我的树莓派pi3上编译dlib库时,发现由于内存不足导致编译失败.树莓派是1G内存,swap只有50M,因此将swap增加到500M,编译通过.具体设置方法如下: 使用free命令带上m参数,查看s ...
- iOS- 关于AVAudioSession的使用——后台播放音乐
1.前言 •AVAudioSession是一个单例,无需实例化即可直接使用.AVAudioSession在各种音频环境中起着非常重要的作用 •针对不同的音频应用场景,需要设置不同的音频会话分类 1 ...