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