sloop公共函数之添加信号,定时器及socket

1:添加信号

  1.1 原型:sloop_handle sloop_register_signal(int sig, sloop_signal_handler handler, void * param)

 1 /* register a signal handler */
 2 sloop_handle sloop_register_signal(int sig, sloop_signal_handler handler, void * param)
 3 {
 4     struct sloop_signal * entry;
 5     struct sigaction sa;
 6
 7     sa.sa_handler = sloop_signals_handler;
 8     sigemptyset(&sa.sa_mask);
 9     sa.sa_flags = SA_RESTART;
10
11     /* allocate a new structure sloop_signal */
12     entry = get_signal();
13     if (entry == NULL)
14         return NULL;
15
16     /* setup structure and insert into list. */
17     entry->sig = sig;
18     entry->param = param;
19     entry->handler = handler;
20     dlist_add(&entry->list, &sloop.signals);
21     SLOOPDBG(d_dbg("sloop: sloop_register_signal(%d)\n", sig));
22     if (sigaction(sig, &sa, NULL) < 0) {
23         dlist_del(&entry->list);
24         free_signal(entry);
25         d_error("sigaction %d error %s\n", sig, strerror(errno));
26         return NULL;
27     }
28
29     return entry;
30 }

  这个函数提供给使用sloop模块的第三方,只需要传入要监听的信号、信号处理函数、参数,就可以将此信号登记到sloop_data结构体中的struct dlist_head signals链表中,在sloop_run函数中进行监听。get_signal函数是从初始化时的struct dlist_head free_signals链表中取出一个可用的节点挂在struct dlist_head signals链表中。具体实现如下:

 1 /* get signal from pool */
 2 static struct sloop_signal * get_signal(void)
 3 {
 4     struct dlist_head * entry;
 5     struct sloop_signal * target;
 6
 7     if (dlist_empty(&sloop.free_signals)) {
 8         d_error("sloop: no sloop_signal available !!!\n");
 9         return NULL;
10     }
11     entry = sloop.free_signals.next;
12     dlist_del(entry);
13     target = dlist_entry(entry, struct sloop_signal, list);
14     target->flags = SLOOP_INUSED | SLOOP_TYPE_SIGNAL;
15     return target;
16 }

  flags参数主要是为了标识此节点的类型,有三种类型,SLOOP_TYPE_SOCKETSLOOP_TYPE_TIMEOUTSLOOP_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)

  同添加信号的实现思路是一样的,需要传递的参数是定时器的秒和微妙参数。

 1 /* register a timer  */
 2 sloop_handle sloop_register_timeout(unsigned int secs, unsigned int usecs, sloop_timeout_handler handler, void * param)
 3 {
 4     struct sloop_timeout * timeout, * tmp;
 5     struct dlist_head * entry;
 6
 7     /* allocate a new struct sloop_timeout. */
 8     timeout = get_timeout();
 9     if (timeout == NULL) return NULL;
10
11     /* get current time */
12     gettimeofday(&timeout->time, NULL);
13     timeout->time.tv_sec += secs;
14     timeout->time.tv_usec += usecs;
15
16     while (timeout->time.tv_usec >= 1000000) {
17         timeout->time.tv_sec++;
18         timeout->time.tv_usec -= 1000000;
19     }
20     timeout->handler = handler;
21     timeout->param = param;
22     INIT_DLIST_HEAD(&timeout->list);
23
24     /* put into the list */
25     if (dlist_empty(&sloop.timeout)) {
26         dlist_add(&timeout->list, &sloop.timeout);
27         SLOOPDBG(d_dbg("sloop: timeout(0x%x) added !\n", timeout));
28         return timeout;
29     }
30
31     entry = sloop.timeout.next;
32     while (entry != &sloop.timeout) {
33         tmp = dlist_entry(entry, struct sloop_timeout, list);
34         if (timercmp(&timeout->time, &tmp->time, < )) break;
35         entry = entry->next;
36     }
37     dlist_add_tail(&timeout->list, entry);
38     SLOOPDBG(d_dbg("sloop: timeout(0x%x) added !!\n", timeout));
39     return timeout;
40 }

  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链表上。

 1 static struct sloop_socket * register_socket(int sock,
 2         sloop_socket_handler handler, void * param, struct dlist_head * head)
 3 {
 4     struct sloop_socket * entry;
 5
 6     /* allocate a new structure sloop_socket */
 7     entry = get_socket();
 8     if (entry == NULL) return NULL;
 9
10     /* setup structure and insert into list. */
11     entry->sock = sock;
12     entry->param = param;
13     entry->handler = handler;
14     dlist_add(&entry->list, head);
15     SLOOPDBG(d_dbg("sloop: new socket : 0x%x (fd=%d)\n", (unsigned int)entry, entry->sock));
16     return entry;
17 }

  get_socket实现:

 1 /* get socket from pool */
 2 static struct sloop_socket * get_socket(void)
 3 {
 4     struct dlist_head * entry;
 5     struct sloop_socket * target;
 6
 7     if (dlist_empty(&sloop.free_sockets)) {
 8         d_error("sloop: no sloop_socket available !!!\n");
 9         return NULL;
10     }
11     entry = sloop.free_sockets.next;
12     SLOOPDBG(daig_printf("%s: get socket sd=[%x],\n", __FILE__, entry));
13     dlist_del(entry);
14     target = dlist_entry(entry, struct sloop_socket, list);
15     target->flags = SLOOP_INUSED | SLOOP_TYPE_SOCKET;
16     return target;
17 }

综上:

  这就是这四种功能的实现思路及使用方式。

时间: 2024-08-10 21:29:40

sloop公共函数之添加信号,定时器及socket的相关文章

添加、移除class类选择器的公共函数

/********************移除class类选择器的公共函数************************///提供需要操作的元素对象以及需要删除的className名即可function removeclassName(element,name){ var classes=element.className.split(' '); if(classes.indexOf(name)!=-1){ classes.splice(classes.indexOf(name)); } el

CI CodeIgniter 添加公共函数 全局函数 自定义函数

CodeIgniter 中公共函数可以通过 helper 辅助函数实现. 创建 common_helper.php 文件,定义所需公共函数,存放至 application/helpers 目录中. 在 application/config/autoload.php 中配置 $autoload['helper'] = array('common'); 即可.

sloop公共程序之初始过程

1:sloop_init() 初始化主要是初始化静态sloop_*** 结构体和填充struct sloop_data 结构体中的成员. 1 //初始化静态存储区给sloop_***结构体 2 static struct sloop_socket _sloop_sockets[MAX_SLOOP_SOCKET]; 3 static struct sloop_timeout _sloop_timeout[MAX_SLOOP_TIMEOUT]; 4 static struct sloop_signa

在Qt Creator 和在 vs2012 里添加信号和槽

Qt  的窗口部件通过发射信号(signal)来表明一个用户的动作已经发生了或者是一个状态已经改变了. 如点击一个QPushButton时,按钮会发送一个clicked()信号,信号可以与函数(在qt里称做槽slot)相连接 可以把信号理解为c#里的事件 在vs2012里和在Qt Creator里添加信号和槽不一样,这里把两种环境下怎么添加详细说明一下 1.在vs2012里添加信号和槽 新建一个qt的项目QtDemo 在qtdeom.h里添加槽 private slots: void Btn_O

【ASP.NET】如何使用类创建公共函数,在不同ASP.NET页面间重复调用

为了减少代码冗余,应将公共函数写在类中,供不同ASP.NET页面调用. 1,先新建一个类,并在类中添加函数逻辑 namespace public_function_demo { public class MyFunction { public static string tbName(string tbNo) { if (tbNo == "510101") { return "3GPP 51.010-1"; } else { return "3GPP 51

公共函数

<?php /** * +=================================================== * 全局项目公共函数库 * +=================================================== */ function showzt($status){    switch ($status) {        case '1':            return '未付款';            break;        

ThinkPHP 3.2.3 自动加载公共函数文件的方法

方法一.加载默认的公共函数文件 在 ThinkPHP 3.2.3 中,默认的公共函数文件位于公共模块 ./Application/Common 下,访问所有的模块之前都会首先加载公共模块下面的配置文件(Conf/config.php)和公共函数文件(Common/function.php),即默认的公共函数文件为 ./Application/Common/Common/function.php. 例如,在 ./Application/Common/Common 下新建 function.php,

thinkphp3.2.2版本,公共函数放哪里才能自动加载?

在原来的项目里面有个common/common.php, 里面放的就是些function,之前能在任何地方直接使用, 现在报错不能使用, 公用函数库文件放置在Application应用模块根目录下的Common模块下的Common目录下即可(./Application/Common/Common/function.php),其他模块直接调用该公用函数文件的函数,命名空间都不需要 thinkphp3.2.2版本,公共函数放哪里才能自动加载?,布布扣,bubuko.com

使用 sigaction 函数实现可靠信号

前言 在前文中,讲述了一个可靠信号的示例.它分成几个步骤组成( 请参考前文 ).在 Linux 系统编程中,有个方法可以将这些步骤给集成起来,让我们使用起来更加的方便.那就是调用 sigaction 函数. sigaction 函数 原型:int sigaction (int signo, const struct sigaction * restrict act, struct sigaction *restrict oact) 作用:将信号及其处理函数关联起来,但这个注册函数中,信号处理函数