r12123: handle fde == NULL at the correct level
[bbaumbach/samba-autobuild/.git] / source4 / lib / events / events_standard.c
1 /* 
2    Unix SMB/CIFS implementation.
3    main select loop and event handling
4    Copyright (C) Andrew Tridgell        2003-2005
5    Copyright (C) Stefan Metzmacher      2005
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /*
23   This is SAMBA's default event loop code
24
25   - we try to use epoll if configure detected support for it
26     otherwise we use select()
27   - if epoll is broken on the system or the kernel doesn't support it
28     at runtime we fallback to select()
29 */
30
31 #include "includes.h"
32 #include "system/filesys.h"
33 #include "dlinklist.h"
34 #include "lib/events/events.h"
35 #include "lib/events/events_internal.h"
36
37 /* use epoll if it is available */
38 #if defined(HAVE_EPOLL_CREATE) && defined(HAVE_SYS_EPOLL_H)
39 #define WITH_EPOLL 1
40 #endif
41
42 #if WITH_EPOLL
43 #include <sys/epoll.h>
44 #endif
45
46 struct std_event_context {
47         /* list of filedescriptor events */
48         struct fd_event *fd_events;
49
50         /* list of timed events */
51         struct timed_event *timed_events;
52
53         /* the maximum file descriptor number in fd_events */
54         int maxfd;
55
56         /* information for exiting from the event loop */
57         int exit_code;
58
59         /* this is changed by the destructors for the fd event
60            type. It is used to detect event destruction by event
61            handlers, which means the code that is calling the event
62            handler needs to assume that the linked list is no longer
63            valid
64         */
65         uint32_t destruction_count;
66
67 #if WITH_EPOLL
68         /* when using epoll this is the handle from epoll_create */
69         int epoll_fd;
70 #endif
71 };
72
73 /*
74   destroy an event context
75 */
76 static int std_event_context_destructor(void *ptr)
77 {
78 #if WITH_EPOLL
79         struct event_context *ev = talloc_get_type(ptr, struct event_context);
80         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
81                                                            struct std_event_context);
82         if (std_ev->epoll_fd != -1) {
83                 close(std_ev->epoll_fd);
84                 std_ev->epoll_fd = -1;
85         }
86 #endif
87         return 0;
88 }
89
90 /*
91   create a std_event_context structure.
92 */
93 static int std_event_context_init(struct event_context *ev, void *privata_data)
94 {
95         struct std_event_context *std_ev;
96
97         std_ev = talloc_zero(ev, struct std_event_context);
98         if (!std_ev) return -1;
99
100 #if WITH_EPOLL
101         std_ev->epoll_fd = epoll_create(64);
102 #endif
103
104         ev->additional_data = std_ev;
105
106         talloc_set_destructor(ev, std_event_context_destructor);
107
108         return 0;
109 }
110
111 /*
112   recalculate the maxfd
113 */
114 static void calc_maxfd(struct event_context *ev)
115 {
116         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
117                                                            struct std_event_context);
118         struct fd_event *fde;
119
120         std_ev->maxfd = 0;
121         for (fde = std_ev->fd_events; fde; fde = fde->next) {
122                 if (fde->fd > std_ev->maxfd) {
123                         std_ev->maxfd = fde->fd;
124                 }
125         }
126 }
127
128
129 /* to mark the ev->maxfd invalid
130  * this means we need to recalculate it
131  */
132 #define EVENT_INVALID_MAXFD (-1)
133
134
135 #if WITH_EPOLL
136 /*
137   called when a epoll call fails, and we should fallback
138   to using select
139 */
140 static void epoll_fallback_to_select(struct event_context *ev, const char *reason)
141 {
142         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
143                                                            struct std_event_context);
144         DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
145         close(std_ev->epoll_fd);
146         std_ev->epoll_fd = -1;
147 }
148 #endif
149
150
151 #if WITH_EPOLL
152 /*
153   map from EVENT_FD_* to EPOLLIN/EPOLLOUT
154 */
155 static uint32_t epoll_map_flags(uint16_t flags)
156 {
157         uint32_t ret = 0;
158         if (flags & EVENT_FD_READ) ret |= EPOLLIN;
159         if (flags & EVENT_FD_WRITE) ret |= EPOLLOUT;
160         return ret;
161 }
162 #endif
163
164 /*
165   destroy an fd_event
166 */
167 static int std_event_fd_destructor(void *ptr)
168 {
169         struct fd_event *fde = talloc_get_type(ptr, struct fd_event);
170         struct event_context *ev = fde->event_ctx;
171         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
172                                                            struct std_event_context);
173
174         if (std_ev->maxfd == fde->fd) {
175                 std_ev->maxfd = EVENT_INVALID_MAXFD;
176         }
177         DLIST_REMOVE(std_ev->fd_events, fde);
178         std_ev->destruction_count++;
179 #if WITH_EPOLL
180         if (std_ev->epoll_fd != -1) {
181                 struct epoll_event event;
182                 ZERO_STRUCT(event);
183                 event.events = epoll_map_flags(fde->flags);
184                 event.data.ptr = fde;
185                 epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
186         }
187 #endif
188         return 0;
189 }
190
191 /*
192   add a fd based event
193   return NULL on failure (memory allocation error)
194 */
195 static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
196                                          int fd, uint16_t flags,
197                                          event_fd_handler_t handler,
198                                          void *private_data)
199 {
200         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
201                                                            struct std_event_context);
202         struct fd_event *fde;
203
204         fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
205         if (!fde) return NULL;
206
207         fde->event_ctx          = ev;
208         fde->fd                 = fd;
209         fde->flags              = flags;
210         fde->handler            = handler;
211         fde->private_data       = private_data;
212         fde->additional_data    = NULL;
213
214         DLIST_ADD(std_ev->fd_events, fde);
215
216         if (fde->fd > std_ev->maxfd) {
217                 std_ev->maxfd = fde->fd;
218         }
219
220         talloc_set_destructor(fde, std_event_fd_destructor);
221
222 #if WITH_EPOLL
223         if (std_ev->epoll_fd != -1) {
224                 struct epoll_event event;
225                 ZERO_STRUCT(event);
226                 event.events = epoll_map_flags(flags);
227                 event.data.ptr = fde;
228                 if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
229                         epoll_fallback_to_select(ev, "EPOLL_CTL_ADD failed");
230                 }
231         }
232 #endif
233
234         return fde;
235 }
236
237
238 /*
239   return the fd event flags
240 */
241 static uint16_t std_event_get_fd_flags(struct fd_event *fde)
242 {
243         return fde->flags;
244 }
245
246 /*
247   set the fd event flags
248 */
249 static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
250 {
251 #if WITH_EPOLL
252         struct event_context *ev;
253         struct std_event_context *std_ev;
254         if (fde->flags == flags) {
255                 return;
256         }
257         ev = fde->event_ctx;
258         std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
259         if (std_ev->epoll_fd != -1) {
260                 struct epoll_event event;
261                 ZERO_STRUCT(event);
262                 event.events = epoll_map_flags(flags);
263                 event.data.ptr = fde;
264                 if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
265                         epoll_fallback_to_select(ev, "EPOLL_CTL_MOD failed");
266                 }
267         }
268 #endif
269         fde->flags = flags;
270 }
271
272 /*
273   destroy a timed event
274 */
275 static int std_event_timed_destructor(void *ptr)
276 {
277         struct timed_event *te = talloc_get_type(ptr, struct timed_event);
278         struct std_event_context *std_ev = talloc_get_type(te->event_ctx->additional_data,
279                                                            struct std_event_context);
280         DLIST_REMOVE(std_ev->timed_events, te);
281         return 0;
282 }
283
284 static int std_event_timed_deny_destructor(void *ptr)
285 {
286         return -1;
287 }
288
289 /*
290   add a timed event
291   return NULL on failure (memory allocation error)
292 */
293 static struct timed_event *std_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
294                                                struct timeval next_event, 
295                                                event_timed_handler_t handler, 
296                                                void *private_data) 
297 {
298         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
299                                                            struct std_event_context);
300         struct timed_event *te, *last_te, *cur_te;
301
302         te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
303         if (te == NULL) return NULL;
304
305         te->event_ctx           = ev;
306         te->next_event          = next_event;
307         te->handler             = handler;
308         te->private_data        = private_data;
309         te->additional_data     = NULL;
310
311         /* keep the list ordered */
312         last_te = NULL;
313         for (cur_te = std_ev->timed_events; cur_te; cur_te = cur_te->next) {
314                 /* if the new event comes before the current one break */
315                 if (!timeval_is_zero(&cur_te->next_event) &&
316                     timeval_compare(&te->next_event,
317                                     &cur_te->next_event) < 0) {
318                         break;
319                 }
320
321                 last_te = cur_te;
322         }
323
324         DLIST_ADD_AFTER(std_ev->timed_events, te, last_te);
325
326         talloc_set_destructor(te, std_event_timed_destructor);
327
328         return te;
329 }
330
331 /*
332   a timer has gone off - call it
333 */
334 static void std_event_loop_timer(struct event_context *ev)
335 {
336         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
337                                                            struct std_event_context);
338         struct timeval t = timeval_current();
339         struct timed_event *te = std_ev->timed_events;
340
341         if (te == NULL) {
342                 return;
343         }
344
345         /* deny the handler to free the event */
346         talloc_set_destructor(te, std_event_timed_deny_destructor);
347
348         /* We need to remove the timer from the list before calling the
349          * handler because in a semi-async inner event loop called from the
350          * handler we don't want to come across this event again -- vl */
351         DLIST_REMOVE(std_ev->timed_events, te);
352
353         te->handler(ev, te, t, te->private_data);
354
355         /* The destructor isn't necessary anymore, we've already removed the
356          * event from the list. */
357         talloc_set_destructor(te, NULL);
358
359         talloc_free(te);
360 }
361
362 #if WITH_EPOLL
363 /*
364   event loop handling using epoll
365 */
366 static int std_event_loop_epoll(struct event_context *ev, struct timeval *tvalp)
367 {
368         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
369                                                            struct std_event_context);
370         int ret, i;
371 #define MAXEVENTS 8
372         struct epoll_event events[MAXEVENTS];
373         uint32_t destruction_count = std_ev->destruction_count;
374         int timeout = -1;
375
376         if (tvalp) {
377                 /* it's better to trigger timed events a bit later than to early */
378                 timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
379         }
380
381         ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
382
383         if (ret == -1 && errno != EINTR) {
384                 epoll_fallback_to_select(ev, "epoll_wait() failed");
385                 return -1;
386         }
387
388         if (ret == 0 && tvalp) {
389                 std_event_loop_timer(ev);
390                 return 0;
391         }
392
393         for (i=0;i<ret;i++) {
394                 struct fd_event *fde = talloc_get_type(events[i].data.ptr, 
395                                                        struct fd_event);
396                 uint16_t flags = 0;
397
398                 if (fde == NULL) {
399                         epoll_fallback_to_select(ev, "epoll_wait() gave bad data");
400                         return -1;
401                 }
402                 if (events[i].events & (EPOLLIN|EPOLLHUP|EPOLLERR)) 
403                         flags |= EVENT_FD_READ;
404                 if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
405                 if (flags) {
406                         fde->handler(ev, fde, flags, fde->private_data);
407                         if (destruction_count != std_ev->destruction_count) {
408                                 break;
409                         }
410                 }
411         }
412
413         return 0;
414 }               
415 #endif
416
417 /*
418   event loop handling using select()
419 */
420 static int std_event_loop_select(struct event_context *ev, struct timeval *tvalp)
421 {
422         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
423                                                            struct std_event_context);
424         fd_set r_fds, w_fds;
425         struct fd_event *fde;
426         int selrtn;
427         uint32_t destruction_count = std_ev->destruction_count;
428
429         /* we maybe need to recalculate the maxfd */
430         if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
431                 calc_maxfd(ev);
432         }
433
434         FD_ZERO(&r_fds);
435         FD_ZERO(&w_fds);
436
437         /* setup any fd events */
438         for (fde = std_ev->fd_events; fde; fde = fde->next) {
439                 if (fde->flags & EVENT_FD_READ) {
440                         FD_SET(fde->fd, &r_fds);
441                 }
442                 if (fde->flags & EVENT_FD_WRITE) {
443                         FD_SET(fde->fd, &w_fds);
444                 }
445         }
446
447         selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
448
449         if (selrtn == -1 && errno == EBADF) {
450                 /* the socket is dead! this should never
451                    happen as the socket should have first been
452                    made readable and that should have removed
453                    the event, so this must be a bug. This is a
454                    fatal error. */
455                 DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
456                 std_ev->exit_code = EBADF;
457                 return -1;
458         }
459
460         if (selrtn == 0 && tvalp) {
461                 std_event_loop_timer(ev);
462                 return 0;
463         }
464
465         if (selrtn > 0) {
466                 /* at least one file descriptor is ready - check
467                    which ones and call the handler, being careful to allow
468                    the handler to remove itself when called */
469                 for (fde = std_ev->fd_events; fde; fde = fde->next) {
470                         uint16_t flags = 0;
471
472                         if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
473                         if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
474                         if (flags) {
475                                 fde->handler(ev, fde, flags, fde->private_data);
476                                 if (destruction_count != std_ev->destruction_count) {
477                                         break;
478                                 }
479                         }
480                 }
481         }
482
483         return 0;
484 }               
485
486 /*
487   do a single event loop using the events defined in ev 
488 */
489 static int std_event_loop_once(struct event_context *ev)
490 {
491         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
492                                                            struct std_event_context);
493         struct timeval tval;
494
495         /* work out the right timeout for all timed events */
496         if (std_ev->timed_events) {
497                 struct timeval t = timeval_current();
498                 tval = timeval_until(&t, &std_ev->timed_events->next_event);
499                 if (timeval_is_zero(&tval)) {
500                         std_event_loop_timer(ev);
501                         return 0;
502                 }
503         } else {
504                 /* have a default tick time of 30 seconds. This guarantees
505                    that code that uses its own timeout checking will be
506                    able to proceeed eventually */
507                 tval = timeval_set(30, 0);
508         }
509
510 #if WITH_EPOLL
511         if (std_ev->epoll_fd != -1) {
512                 if (std_event_loop_epoll(ev, &tval) == 0) {
513                         return 0;
514                 }
515         }
516 #endif
517
518         return std_event_loop_select(ev, &tval);
519 }
520
521 /*
522   return on failure or (with 0) if all fd events are removed
523 */
524 static int std_event_loop_wait(struct event_context *ev)
525 {
526         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
527                                                            struct std_event_context);
528         std_ev->exit_code = 0;
529
530         while (std_ev->fd_events && std_ev->exit_code == 0) {
531                 if (std_event_loop_once(ev) != 0) {
532                         break;
533                 }
534         }
535
536         return std_ev->exit_code;
537 }
538
539 static const struct event_ops std_event_ops = {
540         .context_init   = std_event_context_init,
541         .add_fd         = std_event_add_fd,
542         .get_fd_flags   = std_event_get_fd_flags,
543         .set_fd_flags   = std_event_set_fd_flags,
544         .add_timed      = std_event_add_timed,
545         .loop_once      = std_event_loop_once,
546         .loop_wait      = std_event_loop_wait,
547 };
548
549 const struct event_ops *event_standard_get_ops(void)
550 {
551         return &std_event_ops;
552 }