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。