sloop公共程序之初始过程

Posted 会飞的小丑

tags:

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

 

以上是关于sloop公共程序之初始过程的主要内容,如果未能解决你的问题,请参考以下文章

片段 null 必须是公共静态类才能从实例状态正确重新创建

如何使用 Swift 使用此代码片段为 iOS 应用程序初始化 SDK?

片段事务中的实例化错误

Python之初始面向对象(3--5)

thymeleaf引入公共页面的某个片段

在android studio中升级repo v9后,片段必须是公共静态类崩溃错误