]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/socketengine.h
5c5eca1d2af19f183acc182ca33ed2b6fa18f3ba
[user/henk/code/inspircd.git] / include / socketengine.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2005 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 // Fill the engine with client file descriptors pending an action
18
19 #define epoll_fill      int i = epoll_wait(ep, event, 1, 5); \
20                         if (i > 0) \
21                         { \
22                                 log(DEBUG,"epoll_wait call: ep=%d, i=%d",ep,i); \
23                                 userrec* cu = fd_ref_table[event[0].data.fd];
24
25 #define kqueue_fill     ts.tv_sec = 0; \
26                         ts.tv_nsec = 1000L; \
27                         int i = kevent(kq, NULL, 0, &ke, 1, &ts); \
28                         if (i > 0) \
29                         { \
30                                 log(DEBUG,"kevent call: kq=%d, i=%d",kq,i); \
31                                 userrec* cu = fd_ref_table[ke.ident];
32
33 #define select_fill     tval.tv_sec = 0; \
34                         tval.tv_usec = 1000L; \
35                         selectResult2 = select(FD_SETSIZE, &sfd, NULL, NULL, &tval); \
36                         if ((selectResult2 > 0) && (xcount != clientlist.end())) \
37                         for (user_hash::iterator count2a = xcount; count2a != endingiter; count2a++) \
38                         { \
39                                 if (count2a == clientlist.end()) \
40                                         break; \
41                                 userrec* cu = count2a->second;
42
43 #ifdef USE_EPOLL
44 #define engine_fill epoll_fill
45 #endif
46 #ifdef USE_KQUEUE
47 #define engine_fill kqueue_fill
48 #endif
49 #ifdef USE_SELECT
50 #define engine_fill select_fill
51 #endif
52
53 // how to determine if a socket needs attention if further checks are needed
54
55 #define epoll_check    ((cu->fd != FD_MAGIC_NUMBER) && (cu->fd != -1))
56
57 #define kqueue_check   ((cu->fd != FD_MAGIC_NUMBER) && (cu->fd != -1))
58
59 #define select_check   ((cu->fd != FD_MAGIC_NUMBER) && (cu->fd != -1) && (FD_ISSET (cu->fd, &sfd)))
60
61 #ifdef USE_EPOLL
62 #define engine_check epoll_check
63 #endif
64 #ifdef USE_KQUEUE
65 #define engine_check kqueue_check
66 #endif
67 #ifdef USE_SELECT
68 #define engine_check select_check
69 #endif
70
71 // how to clean up an exiting client
72
73 #define epoll_cleanup                   log(DEBUG,"InspIRCd: Exited: %s",cu->nick); \
74                                         kill_link(cu,"Client exited"); \
75                                         log(DEBUG,"Bailing from client exit"); \
76                                         goto label;
77
78 #define kqueue_cleanup                  log(DEBUG,"InspIRCd: Exited: %s",cu->nick); \
79                                         kill_link(cu,"Client exited"); \
80                                         log(DEBUG,"Bailing from client exit"); \
81                                         goto label;
82
83 #define select_cleanup                  if (count2->second) \
84                                         { \
85                                                 log(DEBUG,"InspIRCd: Exited: %s",cu->nick); \
86                                                 kill_link(cu,"Client exited"); \
87                                                 log(DEBUG,"Bailing from client exit"); \
88                                                 goto label; \
89                                         }
90
91 #ifdef USE_EPOLL
92 #define engine_cleanup epoll_cleanup
93 #endif
94 #ifdef USE_KQUEUE
95 #define engine_cleanup kqueue_cleanup
96 #endif
97 #ifdef USE_SELECT
98 #define engine_cleanup select_cleanup
99 #endif
100
101
102 // how to scan the set for fd's requiring action
103
104 #define select_scanset          for (count = 0; count < boundPortCount; count++) \
105                                 { \
106                                         FD_SET (openSockfd[count], &selectFds); \
107                                 } \
108                                 tv.tv_usec = 30000L; \
109                                 selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv); \
110                                 if (selectResult > 0) \
111                                 { \
112                                         for (count = 0; count < boundPortCount; count++) \
113                                 { \
114                                                 if (FD_ISSET (openSockfd[count], &selectFds)) \
115                                                 {
116
117 #define kqueue_scanset          ts.tv_sec = 0; \
118                                 ts.tv_nsec = 30000L; \
119                                 i = kevent(lkq, NULL, 0, ke_list, 32, &ts); \
120                                 if (i > 0) for (j = 0; j < i; j++) \
121                                 { \
122                                         log(DEBUG,"kqueue: Listening socket event, i=%d, ke.ident=%d",i,ke_list[j].ident); \
123                                         for (count = 0; count < boundPortCount; count++) \
124                                         { \
125                                                 if ((unsigned)ke_list[j].ident == (unsigned)openSockfd[count]) \
126                                                 {
127
128 #define epoll_scanset           i = epoll_wait(lep, event, 32, EP_DELAY); \
129                                 if (i > 0) for (j = 0; j < i; j++) \
130                                 { \
131                                         log(DEBUG,"epoll: Listening socket event, i=%d,events[j].data.fd=%d",i,event[j].data.fd); \
132                                         for (count = 0; count < boundPortCount; count++) \
133                                         { \
134                                                 if ((unsigned)event[j].data.fd == (unsigned)openSockfd[count]) \
135                                                 {
136
137 #ifdef USE_EPOLL
138 #define engine_scanset epoll_scanset
139 #endif
140 #ifdef USE_KQUEUE
141 #define engine_scanset kqueue_scanset
142 #endif
143 #ifdef USE_SELECT
144 #define engine_scanset select_scanset
145 #endif
146
147 // a list of variables used specifically by this engine
148
149 #define kqueue_structs struct kevent ke; \
150         struct kevent ke_list[33]; \
151         struct timespec ts;
152
153 #define epoll_structs struct epoll_event event[33];
154
155 #define select_structs fd_set sfd;
156
157 #ifdef USE_EPOLL
158 #define engine_structs epoll_structs
159 #endif
160 #ifdef USE_KQUEUE
161 #define engine_structs kqueue_structs
162 #endif
163 #ifdef USE_SELECT
164 #define engine_structs select_structs
165 #endif
166
167 // how to initialise the engine before using it
168
169 #define select_init     while(0);
170
171 #define kqueue_init     kq = kqueue(); \
172                         lkq = kqueue(); \
173                         skq = kqueue(); \
174                         if ((kq == -1) || (lkq == -1) || (skq == -1)) \
175                         { \
176                                 log(DEFAULT,"main: kqueue() failed!"); \
177                                 printf("ERROR: could not initialise kqueue event system. Shutting down.\n"); \
178                                 Exit(ERROR); \
179                         }
180
181 #define epoll_init      ep = epoll_create(MAXCLIENTS); \
182                         lep = epoll_create(32); \
183                         sep = epoll_create(128); \
184                         if ((ep == -1) || (lep == -1) || (sep == -1)) \
185                         { \
186                                 log(DEFAULT,"main: epoll_create() failed!"); \
187                                 printf("ERROR: could not initialise epoll event system. Shutting down.\n"); \
188                                 Exit(ERROR); \
189                         }
190
191
192 #ifdef USE_EPOLL
193 #define engine_init epoll_init
194 #endif
195 #ifdef USE_KQUEUE
196 #define engine_init kqueue_init
197 #endif
198 #ifdef USE_SELECT
199 #define engine_init select_init
200 #endif
201
202 // how to delete a client fd from the engine
203
204 #define kqueue_delete_fd        struct kevent ke; \
205                                 EV_SET(&ke, user->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); \
206                                 int i = kevent(kq, &ke, 1, 0, 0, NULL); \
207                                 if (i == -1) \
208                                 { \
209                                         log(DEBUG,"kqueue: Failed to remove user from queue!"); \
210                                 }
211
212 #define epoll_delete_fd         struct epoll_event ev; \
213                                 ev.events = EPOLLIN | EPOLLET; \
214                                 ev.data.fd = user->fd; \
215                                 int i = epoll_ctl(ep, EPOLL_CTL_DEL, user->fd, &ev); \
216                                 if (i < 0) \
217                                 { \
218                                         log(DEBUG,"epoll: List deletion failure!"); \
219                                 }
220
221 #define select_delete_fd        while(0);
222
223
224 #ifdef USE_EPOLL
225 #define engine_delete_fd epoll_delete_fd
226 #endif
227 #ifdef USE_KQUEUE
228 #define engine_delete_fd kqueue_delete_fd
229 #endif
230 #ifdef USE_SELECT
231 #define engine_delete_fd select_delete_fd
232 #endif
233
234 // how to add a client fd to the engine
235
236 #define select_add_fd           while(0);
237
238 #define epoll_add_fd            struct epoll_event ev; \
239                                 log(DEBUG,"epoll: Adduser to events, ep=%d socket=%d",ep,socket); \
240                                 ev.events = EPOLLIN | EPOLLET; \
241                                 ev.data.fd = socket; \
242                                 int i = epoll_ctl(ep, EPOLL_CTL_ADD, socket, &ev); \
243                                 if (i < 0) \
244                                 { \
245                                         log(DEBUG,"epoll: List insertion failure!"); \
246                                 }
247
248 #define kqueue_add_fd           struct kevent ke; \
249                                 log(DEBUG,"kqueue: Add user to events, kq=%d socket=%d",kq,socket);\
250                                 EV_SET(&ke, socket, EVFILT_READ, EV_ADD, 0, 0, NULL); \
251                                 int i = kevent(kq, &ke, 1, 0, 0, NULL); \
252                                 if (i == -1) \
253                                 { \
254                                         log(DEBUG,"kqueue: List insertion failure!"); \
255                                 }
256
257 #ifdef USE_EPOLL
258 #define engine_add_fd epoll_add_fd
259 #endif
260 #ifdef USE_KQUEUE
261 #define engine_add_fd kqueue_add_fd
262 #endif
263 #ifdef USE_SELECT
264 #define engine_add_fd select_add_fd
265 #endif
266
267 // what is this engine called?
268
269 #ifdef USE_KQUEUE
270 #define engine_name "kqueue"
271 #endif
272 #ifdef USE_SELECT
273 #define engine_name "select"
274 #endif
275 #ifdef USE_EPOLL
276 #define engine_name "epoll"
277 #endif
278