ff11afe5d552e13116eb0fc004b1b364d246a52c
[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 "system/select.h" /* needed for WITH_EPOLL */
34 #include "dlinklist.h"
35 #include "lib/events/events.h"
36 #include "lib/events/events_internal.h"
37
38 struct std_event_context {
39         /* a pointer back to the generic event_context */
40         struct event_context *ev;
41
42         /* list of filedescriptor events */
43         struct fd_event *fd_events;
44
45         /* list of timed events */
46         struct timed_event *timed_events;
47
48         /* the maximum file descriptor number in fd_events */
49         int maxfd;
50
51         /* information for exiting from the event loop */
52         int exit_code;
53
54         /* this is changed by the destructors for the fd event
55            type. It is used to detect event destruction by event
56            handlers, which means the code that is calling the event
57            handler needs to assume that the linked list is no longer
58            valid
59         */
60         uint32_t destruction_count;
61
62         /* when using epoll this is the handle from epoll_create */
63         int epoll_fd;
64 };
65
66 static void std_event_loop_timer(struct std_event_context *std_ev);
67
68 /* use epoll if it is available */
69 #if WITH_EPOLL
70 /*
71   called when a epoll call fails, and we should fallback
72   to using select
73 */
74 static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
75 {
76         DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
77         close(std_ev->epoll_fd);
78         std_ev->epoll_fd = -1;
79         talloc_set_destructor(std_ev, NULL);
80 }
81
82 /*
83   map from EVENT_FD_* to EPOLLIN/EPOLLOUT
84 */
85 static uint32_t epoll_map_flags(uint16_t flags)
86 {
87         uint32_t ret = 0;
88         if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
89         if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
90         return ret;
91 }
92
93 /*
94  free the epoll fd
95 */
96 static int epoll_ctx_destructor(void *ptr)
97 {
98         struct std_event_context *std_ev = talloc_get_type(ptr,
99                                                            struct std_event_context);
100         close(std_ev->epoll_fd);
101         std_ev->epoll_fd = -1;
102         return 0;
103 }
104
105 /*
106  init the epoll fd
107 */
108 static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
109 {
110         if (!try_epoll) return;
111         std_ev->epoll_fd = epoll_create(64);
112         talloc_set_destructor(std_ev, epoll_ctx_destructor);
113 }
114
115 #define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT      (1<<0)
116 #define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR   (1<<1)
117 #define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR      (1<<2)
118
119 /*
120  add the epoll event to the given fd_event
121 */
122 static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
123 {
124         struct epoll_event event;
125         if (std_ev->epoll_fd == -1) return;
126
127         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
128
129         /* if we don't want events yet, don't add an epoll_event */
130         if (fde->flags == 0) return;
131
132         ZERO_STRUCT(event);
133         event.events = epoll_map_flags(fde->flags);
134         event.data.ptr = fde;
135         if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
136                 epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
137         }
138         fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
139
140         /* only if we want to read we want to tell the event handler about errors */
141         if (fde->flags & EVENT_FD_READ) {
142                 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
143         }
144 }
145
146 /*
147  delete the epoll event for given fd_event
148 */
149 static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
150 {
151         struct epoll_event event;
152         if (std_ev->epoll_fd == -1) return;
153
154         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
155
156         /* if there's no epoll_event, we don't need to delete it */
157         if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
158
159         ZERO_STRUCT(event);
160         event.events = epoll_map_flags(fde->flags);
161         event.data.ptr = fde;
162         epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
163         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
164 }
165
166 /*
167  change the epoll event to the given fd_event
168 */
169 static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
170 {
171         struct epoll_event event;
172         if (std_ev->epoll_fd == -1) return;
173
174         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
175
176         ZERO_STRUCT(event);
177         event.events = epoll_map_flags(fde->flags);
178         event.data.ptr = fde;
179         if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
180                 epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
181         }
182
183         /* only if we want to read we want to tell the event handler about errors */
184         if (fde->flags & EVENT_FD_READ) {
185                 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
186         }
187 }
188
189 static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde)
190 {
191         BOOL got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
192         BOOL want_read = (fde->flags & EVENT_FD_READ);
193         BOOL want_write= (fde->flags & EVENT_FD_WRITE);
194
195         if (std_ev->epoll_fd == -1) return;
196
197         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
198
199         /* there's already an event */
200         if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
201                 if (want_read || (want_write && !got_error)) {
202                         epoll_mod_event(std_ev, fde);
203                         return;
204                 }
205                 /* 
206                  * if we want to match the select behavior, we need to remove the epoll_event
207                  * when the caller isn't interested in events.
208                  *
209                  * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
210                  */
211                 epoll_del_event(std_ev, fde);
212                 return;
213         }
214
215         /* there's no epoll_event attached to the fde */
216         if (want_read || (want_write && !got_error)) {
217                 epoll_add_event(std_ev, fde);
218                 return;
219         }
220 }
221
222 /*
223   event loop handling using epoll
224 */
225 static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
226 {
227         int ret, i;
228 #define MAXEVENTS 8
229         struct epoll_event events[MAXEVENTS];
230         uint32_t destruction_count = std_ev->destruction_count;
231         int timeout = -1;
232
233         if (std_ev->epoll_fd == -1) return -1;
234
235         if (tvalp) {
236                 /* it's better to trigger timed events a bit later than to early */
237                 timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
238         }
239
240         ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
241
242         if (ret == -1 && errno != EINTR) {
243                 epoll_fallback_to_select(std_ev, "epoll_wait() failed");
244                 return -1;
245         }
246
247         if (ret == 0 && tvalp) {
248                 std_event_loop_timer(std_ev);
249                 return 0;
250         }
251
252         for (i=0;i<ret;i++) {
253                 struct fd_event *fde = talloc_get_type(events[i].data.ptr, 
254                                                        struct fd_event);
255                 uint16_t flags = 0;
256
257                 if (fde == NULL) {
258                         epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
259                         return -1;
260                 }
261                 if (events[i].events & (EPOLLHUP|EPOLLERR)) {
262                         fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
263                         /*
264                          * if we only wait for EVENT_FD_WRITE, we should not tell the
265                          * event handler about it, and remove the epoll_event,
266                          * as we only report errors when waiting for read events,
267                          * to match the select() behavior
268                          */
269                         if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
270                                 epoll_del_event(std_ev, fde);
271                                 continue;
272                         }
273                         flags |= EVENT_FD_READ;
274                 }
275                 if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
276                 if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
277                 if (flags) {
278                         fde->handler(std_ev->ev, fde, flags, fde->private_data);
279                         if (destruction_count != std_ev->destruction_count) {
280                                 break;
281                         }
282                 }
283         }
284
285         return 0;
286 }
287 #else
288 #define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
289 #define epoll_add_event(std_ev,fde)
290 #define epoll_del_event(std_ev,fde)
291 #define epoll_change_event(std_ev,fde)
292 #define epoll_event_loop(std_ev,tvalp) (-1)
293 #endif
294
295 /*
296   create a std_event_context structure.
297 */
298 static int std_event_context_init(struct event_context *ev, void *private_data)
299 {
300         struct std_event_context *std_ev;
301         BOOL *_try_epoll = private_data;
302         BOOL try_epoll = (_try_epoll == NULL ? True : *_try_epoll);
303
304         std_ev = talloc_zero(ev, struct std_event_context);
305         if (!std_ev) return -1;
306         std_ev->ev = ev;
307         std_ev->epoll_fd = -1;
308
309         epoll_init_ctx(std_ev, try_epoll);
310
311         ev->additional_data = std_ev;
312         return 0;
313 }
314
315 /*
316   recalculate the maxfd
317 */
318 static void calc_maxfd(struct std_event_context *std_ev)
319 {
320         struct fd_event *fde;
321
322         std_ev->maxfd = 0;
323         for (fde = std_ev->fd_events; fde; fde = fde->next) {
324                 if (fde->fd > std_ev->maxfd) {
325                         std_ev->maxfd = fde->fd;
326                 }
327         }
328 }
329
330
331 /* to mark the ev->maxfd invalid
332  * this means we need to recalculate it
333  */
334 #define EVENT_INVALID_MAXFD (-1)
335
336 /*
337   destroy an fd_event
338 */
339 static int std_event_fd_destructor(void *ptr)
340 {
341         struct fd_event *fde = talloc_get_type(ptr, struct fd_event);
342         struct event_context *ev = fde->event_ctx;
343         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
344                                                            struct std_event_context);
345
346         if (std_ev->maxfd == fde->fd) {
347                 std_ev->maxfd = EVENT_INVALID_MAXFD;
348         }
349
350         DLIST_REMOVE(std_ev->fd_events, fde);
351         std_ev->destruction_count++;
352
353         epoll_del_event(std_ev, fde);
354
355         return 0;
356 }
357
358 /*
359   add a fd based event
360   return NULL on failure (memory allocation error)
361 */
362 static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
363                                          int fd, uint16_t flags,
364                                          event_fd_handler_t handler,
365                                          void *private_data)
366 {
367         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
368                                                            struct std_event_context);
369         struct fd_event *fde;
370
371         fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
372         if (!fde) return NULL;
373
374         fde->event_ctx          = ev;
375         fde->fd                 = fd;
376         fde->flags              = flags;
377         fde->handler            = handler;
378         fde->private_data       = private_data;
379         fde->additional_flags   = 0;
380         fde->additional_data    = NULL;
381
382         DLIST_ADD(std_ev->fd_events, fde);
383         if (fde->fd > std_ev->maxfd) {
384                 std_ev->maxfd = fde->fd;
385         }
386         talloc_set_destructor(fde, std_event_fd_destructor);
387
388         epoll_add_event(std_ev, fde);
389
390         return fde;
391 }
392
393
394 /*
395   return the fd event flags
396 */
397 static uint16_t std_event_get_fd_flags(struct fd_event *fde)
398 {
399         return fde->flags;
400 }
401
402 /*
403   set the fd event flags
404 */
405 static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
406 {
407         struct event_context *ev;
408         struct std_event_context *std_ev;
409
410         if (fde->flags == flags) return;
411
412         ev = fde->event_ctx;
413         std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
414
415         fde->flags = flags;
416
417         epoll_change_event(std_ev, fde);
418 }
419
420 /*
421   destroy a timed event
422 */
423 static int std_event_timed_destructor(void *ptr)
424 {
425         struct timed_event *te = talloc_get_type(ptr, struct timed_event);
426         struct std_event_context *std_ev = talloc_get_type(te->event_ctx->additional_data,
427                                                            struct std_event_context);
428         DLIST_REMOVE(std_ev->timed_events, te);
429         return 0;
430 }
431
432 static int std_event_timed_deny_destructor(void *ptr)
433 {
434         return -1;
435 }
436
437 /*
438   add a timed event
439   return NULL on failure (memory allocation error)
440 */
441 static struct timed_event *std_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
442                                                struct timeval next_event, 
443                                                event_timed_handler_t handler, 
444                                                void *private_data) 
445 {
446         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
447                                                            struct std_event_context);
448         struct timed_event *te, *last_te, *cur_te;
449
450         te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
451         if (te == NULL) return NULL;
452
453         te->event_ctx           = ev;
454         te->next_event          = next_event;
455         te->handler             = handler;
456         te->private_data        = private_data;
457         te->additional_data     = NULL;
458
459         /* keep the list ordered */
460         last_te = NULL;
461         for (cur_te = std_ev->timed_events; cur_te; cur_te = cur_te->next) {
462                 /* if the new event comes before the current one break */
463                 if (!timeval_is_zero(&cur_te->next_event) &&
464                     timeval_compare(&te->next_event,
465                                     &cur_te->next_event) < 0) {
466                         break;
467                 }
468
469                 last_te = cur_te;
470         }
471
472         DLIST_ADD_AFTER(std_ev->timed_events, te, last_te);
473
474         talloc_set_destructor(te, std_event_timed_destructor);
475
476         return te;
477 }
478
479 /*
480   a timer has gone off - call it
481 */
482 static void std_event_loop_timer(struct std_event_context *std_ev)
483 {
484         struct timeval t = timeval_current();
485         struct timed_event *te = std_ev->timed_events;
486
487         if (te == NULL) {
488                 return;
489         }
490
491         /* deny the handler to free the event */
492         talloc_set_destructor(te, std_event_timed_deny_destructor);
493
494         /* We need to remove the timer from the list before calling the
495          * handler because in a semi-async inner event loop called from the
496          * handler we don't want to come across this event again -- vl */
497         DLIST_REMOVE(std_ev->timed_events, te);
498
499         te->handler(std_ev->ev, te, t, te->private_data);
500
501         /* The destructor isn't necessary anymore, we've already removed the
502          * event from the list. */
503         talloc_set_destructor(te, NULL);
504
505         talloc_free(te);
506 }
507
508 /*
509   event loop handling using select()
510 */
511 static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
512 {
513         fd_set r_fds, w_fds;
514         struct fd_event *fde;
515         int selrtn;
516         uint32_t destruction_count = std_ev->destruction_count;
517
518         /* we maybe need to recalculate the maxfd */
519         if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
520                 calc_maxfd(std_ev);
521         }
522
523         FD_ZERO(&r_fds);
524         FD_ZERO(&w_fds);
525
526         /* setup any fd events */
527         for (fde = std_ev->fd_events; fde; fde = fde->next) {
528                 if (fde->flags & EVENT_FD_READ) {
529                         FD_SET(fde->fd, &r_fds);
530                 }
531                 if (fde->flags & EVENT_FD_WRITE) {
532                         FD_SET(fde->fd, &w_fds);
533                 }
534         }
535
536         selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
537
538         if (selrtn == -1 && errno == EBADF) {
539                 /* the socket is dead! this should never
540                    happen as the socket should have first been
541                    made readable and that should have removed
542                    the event, so this must be a bug. This is a
543                    fatal error. */
544                 DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
545                 std_ev->exit_code = EBADF;
546                 return -1;
547         }
548
549         if (selrtn == 0 && tvalp) {
550                 std_event_loop_timer(std_ev);
551                 return 0;
552         }
553
554         if (selrtn > 0) {
555                 /* at least one file descriptor is ready - check
556                    which ones and call the handler, being careful to allow
557                    the handler to remove itself when called */
558                 for (fde = std_ev->fd_events; fde; fde = fde->next) {
559                         uint16_t flags = 0;
560
561                         if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
562                         if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
563                         if (flags) {
564                                 fde->handler(std_ev->ev, fde, flags, fde->private_data);
565                                 if (destruction_count != std_ev->destruction_count) {
566                                         break;
567                                 }
568                         }
569                 }
570         }
571
572         return 0;
573 }               
574
575 /*
576   do a single event loop using the events defined in ev 
577 */
578 static int std_event_loop_once(struct event_context *ev)
579 {
580         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
581                                                            struct std_event_context);
582         struct timeval tval;
583
584         /* work out the right timeout for all timed events */
585         if (std_ev->timed_events) {
586                 struct timeval t = timeval_current();
587                 tval = timeval_until(&t, &std_ev->timed_events->next_event);
588                 if (timeval_is_zero(&tval)) {
589                         std_event_loop_timer(std_ev);
590                         return 0;
591                 }
592         } else {
593                 /* have a default tick time of 30 seconds. This guarantees
594                    that code that uses its own timeout checking will be
595                    able to proceeed eventually */
596                 tval = timeval_set(30, 0);
597         }
598
599         if (epoll_event_loop(std_ev, &tval) == 0) {
600                 return 0;
601         }
602
603         return std_event_loop_select(std_ev, &tval);
604 }
605
606 /*
607   return on failure or (with 0) if all fd events are removed
608 */
609 static int std_event_loop_wait(struct event_context *ev)
610 {
611         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
612                                                            struct std_event_context);
613         std_ev->exit_code = 0;
614
615         while (std_ev->fd_events && std_ev->exit_code == 0) {
616                 if (std_event_loop_once(ev) != 0) {
617                         break;
618                 }
619         }
620
621         return std_ev->exit_code;
622 }
623
624 static const struct event_ops std_event_ops = {
625         .context_init   = std_event_context_init,
626         .add_fd         = std_event_add_fd,
627         .get_fd_flags   = std_event_get_fd_flags,
628         .set_fd_flags   = std_event_set_fd_flags,
629         .add_timed      = std_event_add_timed,
630         .loop_once      = std_event_loop_once,
631         .loop_wait      = std_event_loop_wait,
632 };
633
634 const struct event_ops *event_standard_get_ops(void)
635 {
636         return &std_event_ops;
637 }