• 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)
    ", sig));
    22     if (sigaction(sig, &sa, NULL) < 0) {
    23         dlist_del(&entry->list);
    24         free_signal(entry);
    25         d_error("sigaction %d error %s
    ", 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 !!!
    ");
     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 !
    ", 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 !!
    ", 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)
    ", (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 !!!
    ");
     9         return NULL;
    10     }
    11     entry = sloop.free_sockets.next;
    12     SLOOPDBG(daig_printf("%s: get socket sd=[%x],
    ", __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 }

    综上:

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

  • 相关阅读:
    CentOS下部署Django线上运行环境
    MAC 下安装mysqlclient、Homebrew踩坑记
    kali基本命令(-)
    关于Django出现“__str__ returned non-string (type NoneType)”错误的处理
    deepin升级时出现“E: 无法获得锁 /var/lib/apt/lists/lock
    RCNN训练过程
    Jupyter Notebook中使用虚拟环境
    pytorch(cuda)的安装
    conda的基本操作
    第一周、深度学习概念
  • 原文地址:https://www.cnblogs.com/Flychown/p/7109609.html
Copyright © 2020-2023  润新知