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 !!\n");
 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!\n");
 62                 continue;
 63             } else {
 64                 d_error("sloop: sloop_run(): select error (%s)!\n", 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\n", strerror(errno));
 74             } else if (sig == 0) {
 75                 d_info("sloop: get myself signal !!\n");
 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 !!\n"));
 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 !!!\n", 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

 

转载于:https://www.cnblogs.com/Flychown/p/7099091.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值