首页 > 代码库 > sloop公共程序之初始过程

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 =http://www.mamicode.com/ 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             else111             {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             else131             {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                 else147                     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                 else169                     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公共程序之初始过程