• 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_signal  _sloop_signals[MAX_SLOOP_SIGNAL];
     5 
     6 /* sloop module initialization */
     7 void sloop_init(void * sloop_data)
     8 {
     9     memset(&sloop, 0, sizeof(sloop));
    10     INIT_DLIST_HEAD(&sloop.readers);
    11     INIT_DLIST_HEAD(&sloop.writers);
    12     INIT_DLIST_HEAD(&sloop.signals);
    13     INIT_DLIST_HEAD(&sloop.timeout);
    14     INIT_DLIST_HEAD(&sloop.free_sockets);
    15     INIT_DLIST_HEAD(&sloop.free_timeout);
    16     INIT_DLIST_HEAD(&sloop.free_signals);
    17     init_list_pools();
    18     pipe(sloop.signal_pipe);
    19     sloop.sloop_data = sloop_data;
    20 }
    21 
    22 
    23 /* initialize list pools */
    24 static void init_list_pools(void)
    25 {
    26     int i;
    27     memset(_sloop_sockets, 0, sizeof(_sloop_sockets));
    28     memset(_sloop_timeout, 0, sizeof(_sloop_timeout));
    29     memset(_sloop_signals, 0, sizeof(_sloop_signals));
    30     for (i=0; i<MAX_SLOOP_SOCKET; i++) dlist_add(&_sloop_sockets[i].list, &sloop.free_sockets);
    31     for (i=0; i<MAX_SLOOP_TIMEOUT;i++) dlist_add(&_sloop_timeout[i].list, &sloop.free_timeout);
    32     for (i=0; i<MAX_SLOOP_SIGNAL; i++) dlist_add(&_sloop_signals[i].list, &sloop.free_signals);
    33 }

      执行完sloop_init函数之后,静态数组_sloop_sockets、_sloop_signals、_sloop_timeout中的所有成员都被挂载到了sloop.free_sockets、sloop.free_timeout、sloop.free_signals这三个双链表中,表示可使用的链表,等待调用者。

    2:sloop_run()

      此函数启动循环进行监听,监听是sloop.terminate全局变量控制,这个变量由信号控制。

      1 void sloop_run(void)
      2 {
      3     fd_set rfds;
      4     fd_set wfds;
      5     struct timeval tv, now;
      6     struct sloop_timeout * entry_timeout = NULL;
      7     struct sloop_socket * entry_socket;
      8     struct sloop_signal * entry_signal;
      9     struct dlist_head * entry;
     10     int max_sock;
     11     int res;
     12     int sig;
     13     // 开始循环
     14     while (!sloop.terminate) {
     15         /* 是否有定时器加入 */
     16         if (!dlist_empty(&sloop.timeout)) {
     17             entry = sloop.timeout.next;
     18             entry_timeout = dlist_entry(entry, struct sloop_timeout, list);
     19         } else {
     20             entry_timeout = NULL;
     21         }
     22         /* 有定时器 */
     23         if (entry_timeout) {
     24             /* 获取当前时间 */
     25             gettimeofday(&now, NULL);
     26             /* 当前时间>=定时器表示应该执行定时器的回调函数了 */
     27             if (timercmp(&now, &entry_timeout->time, >= ))
     28                 tv.tv_sec = tv.tv_usec = 0;/* tv是select函数的timeout,直接置0表示不阻塞 */
     29             else
     30                 timersub(&entry_timeout->time, &now, &tv);/* 否则阻塞 '当前时间-到期时间' */
     31         }
     32 
     33         /* 清空读写描述符集合 */
     34         FD_ZERO(&rfds);
     35         FD_ZERO(&wfds);
     36         max_sock = 0;
     37 
     38         /* 添加信号可读转状态 */
     39         FD_SET(sloop.signal_pipe[0], &rfds);
     40         if (max_sock < sloop.signal_pipe[0]) max_sock = sloop.signal_pipe[0];
     41 
     42         /* 添加套接字可读转状态 */
     43         for (entry = sloop.readers.next; entry != &sloop.readers; entry = entry->next) {
     44             entry_socket = dlist_entry(entry, struct sloop_socket, list);
     45             FD_SET(entry_socket->sock, &rfds);
     46             if (max_sock < entry_socket->sock) max_sock = entry_socket->sock;
     47         }
     48         /* 添加套接字可写转状态 */
     49         for (entry = sloop.writers.next; entry != &sloop.writers; entry = entry->next) {
     50             entry_socket = dlist_entry(entry, struct sloop_socket, list);
     51             FD_SET(entry_socket->sock, &wfds);
     52             if (max_sock < entry_socket->sock) max_sock = entry_socket->sock;
     53         }
     54 
     55         d_dbg("sloop: >>> enter select sloop !!
    ");
     56         res = select(max_sock + 1, &rfds, &wfds, NULL, entry_timeout ? &tv : NULL);
     57 
     58         if (res < 0) {
     59             /* 意外被中断 */
     60             if (errno == EINTR) {
     61                 d_info("sloop: sloop_run(): EINTR!
    ");
     62                 continue;
     63             } else {
     64                 d_error("sloop: sloop_run(): select error (%s)!
    ", strerror(errno));
     65                 break;
     66             }
     67         }
     68 
     69         /* 先检查信号 */
     70         if (res > 0 && FD_ISSET(sloop.signal_pipe[0], &rfds)) {
     71             if (read(sloop.signal_pipe[0], &sig, sizeof(sig)) < 0) {
     72                 /* probabaly just EINTR */
     73                 d_error("sloop: sloop_run(): Could not read signal: %s
    ", strerror(errno));
     74             } else if (sig == 0) {
     75                 d_info("sloop: get myself signal !!
    ");
     76             } else if (!dlist_empty(&sloop.signals)) {
     77                 for (entry = sloop.signals.next; entry != &sloop.signals; entry = entry->next) {
     78                     entry_signal = dlist_entry(entry, struct sloop_signal, list);
     79                     /* 通过信号值找到登记的信号结构体并执行回调函数 */
     80                     if (entry_signal->sig == sig) {
     81                         if (entry_signal->handler(entry_signal->sig, entry_signal->param, sloop.sloop_data) < 0) {
     82                             dlist_del(entry);
     83                             free_signal(entry_signal);
     84                         }
     85                         break;
     86                     }
     87                 }
     88                 if (sloop.terminate) break;
     89             } else {
     90                 SLOOPDBG(d_info("sloop: should not be here !!
    "));
     91             }
     92         }
     93 
     94         /* 检查定时器 */
     95         if (entry_timeout) {
     96             if (sloop.timeout.next == &entry_timeout->list) {
     97                 gettimeofday(&now, NULL);
     98                 if (res == 0 || timercmp(&now, &entry_timeout->time, >= )) {
     99                     /* 当前时间>=到期时间就调用回调函数 */
    100                     if (entry_timeout->handler)
    101                         entry_timeout->handler(entry_timeout->param, sloop.sloop_data);
    102                     dlist_del(&entry_timeout->list);//删除了定时器
    103                     free_timeout(entry_timeout);//将此定时器又归还给free_timeout双链表
    104                 }
    105             } else {
    106                 SLOOPDBG(d_info("sloop: timeout (0x%x) is gone, should be canceled !!!
    ", entry_timeout));
    107             }
    108         }
    109 
    110         /* 检查可读状态 */
    111         if (!dlist_empty(&sloop.readers)) {
    112             entry = sloop.readers.next;
    113             while (entry != &sloop.readers) {
    114                 /* dlist_entry函数通过list指针获得指向list所在结构体的指针 */
    115                 entry_socket = dlist_entry(entry, struct sloop_socket, list);
    116                 if (FD_ISSET(entry_socket->sock, &rfds))/* 读状态就绪执行回调函数 */
    117                     res = entry_socket->handler(entry_socket->sock, entry_socket->param, sloop.sloop_data);
    118                 else
    119                     res = 0;
    120                 entry = entry->next;
    121 
    122                 /* 不同于定时器,只有回调函数返回错误才将此结构归还给free_readers,否则一直会监听此描述符 */
    123                 if (res < 0) {
    124                     dlist_del(&entry_socket->list);
    125                     free_socket(entry_socket);
    126                 }
    127             }
    128         }
    129 
    130         /* 检查可写状态 */
    131         if (!dlist_empty(&sloop.writers)) {
    132             entry = sloop.writers.next;
    133             while (entry != &sloop.writers) {
    134                 entry_socket = dlist_entry(entry, struct sloop_socket, list);
    135                 if (FD_ISSET(entry_socket->sock, &wfds))
    136                     res = entry_socket->handler(entry_socket->sock, entry_socket->param, sloop.sloop_data);
    137                 else
    138                     res = 0;
    139                 entry = entry->next;
    140 
    141                 if (res < 0) {
    142                     dlist_del(&entry_socket->list);
    143                     free_socket(entry_socket);
    144                 }
    145             }
    146         }
    147     }
    148     /* 在退出循环时要将所有的都归还给free_***结构体 */
    149     sloop_cancel_signal(NULL);
    150     sloop_cancel_timeout(NULL);
    151     sloop_cancel_read_sock(NULL);
    152     sloop_cancel_write_sock(NULL);
    153 }

       目前来讲,在sloop_data结构体中,struct dlist_head readers,struct dlist_head writers,struct dlist_head signals,struct dlist_head timeout,等链表都是空的,所以sloop_run其实没有做任何工作,要想真正起作用就需要将需要监听的套接字、定时器、信号等加入上上面三个链表中来。下一篇:sloop公共函数之添加信号,定时器及socket

  • 相关阅读:
    oracle问题之死锁 (一)
    linux下oracle调试小知识
    Oracle实例名,服务名等概念区别与联系
    oracle 数据库、实例、服务名、SID
    Linux下启动/关闭Oracle
    Oracle监听器
    Oracle数据库、实例、用户、表空间、表之间的关系
    在Centos7上安装Oracle
    理财入门书籍
    [C/C++] VS 2015 C++ 插件
  • 原文地址:https://www.cnblogs.com/Flychown/p/7099091.html
Copyright © 2020-2023  润新知