lib/tevent: change to LGPLv3+
[ira/wip.git] / lib / tevent / tevent_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-2009
6
7      ** NOTE! The following LGPL license applies to the tevent
8      ** library. This does NOT imply that all of Samba is released
9      ** under the LGPL
10
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Lesser General Public
13    License as published by the Free Software Foundation; either
14    version 3 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Lesser General Public License for more details.
20
21    You should have received a copy of the GNU Lesser General Public
22    License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 */
24
25 /*
26   This is SAMBA's default event loop code
27
28   - we try to use epoll if configure detected support for it
29     otherwise we use select()
30   - if epoll is broken on the system or the kernel doesn't support it
31     at runtime we fallback to select()
32 */
33
34 #include "replace.h"
35 #include "system/filesys.h"
36 #include "system/select.h"
37 #include "tevent.h"
38 #include "tevent_util.h"
39 #include "tevent_internal.h"
40
41 struct std_event_context {
42         /* a pointer back to the generic event_context */
43         struct tevent_context *ev;
44
45         /* the maximum file descriptor number in fd_events */
46         int maxfd;
47
48         /* information for exiting from the event loop */
49         int exit_code;
50
51         /* this is changed by the destructors for the fd event
52            type. It is used to detect event destruction by event
53            handlers, which means the code that is calling the event
54            handler needs to assume that the linked list is no longer
55            valid
56         */
57         uint32_t destruction_count;
58
59         /* when using epoll this is the handle from epoll_create */
60         int epoll_fd;
61
62         /* our pid at the time the epoll_fd was created */
63         pid_t pid;
64 };
65
66 /* use epoll if it is available */
67 #if HAVE_EPOLL
68 /*
69   called when a epoll call fails, and we should fallback
70   to using select
71 */
72 static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
73 {
74         tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
75                      "%s (%s) - falling back to select()\n",
76                      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 TEVENT_FD_* to EPOLLIN/EPOLLOUT
84 */
85 static uint32_t epoll_map_flags(uint16_t flags)
86 {
87         uint32_t ret = 0;
88         if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
89         if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
90         return ret;
91 }
92
93 /*
94  free the epoll fd
95 */
96 static int epoll_ctx_destructor(struct std_event_context *std_ev)
97 {
98         if (std_ev->epoll_fd != -1) {
99                 close(std_ev->epoll_fd);
100         }
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)
109 {
110         std_ev->epoll_fd = epoll_create(64);
111         std_ev->pid = getpid();
112         talloc_set_destructor(std_ev, epoll_ctx_destructor);
113 }
114
115 static void epoll_add_event(struct std_event_context *std_ev, struct tevent_fd *fde);
116
117 /*
118   reopen the epoll handle when our pid changes
119   see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an 
120   demonstration of why this is needed
121  */
122 static void epoll_check_reopen(struct std_event_context *std_ev)
123 {
124         struct tevent_fd *fde;
125
126         if (std_ev->pid == getpid()) {
127                 return;
128         }
129
130         close(std_ev->epoll_fd);
131         std_ev->epoll_fd = epoll_create(64);
132         if (std_ev->epoll_fd == -1) {
133                 tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
134                              "Failed to recreate epoll handle after fork\n");
135                 return;
136         }
137         std_ev->pid = getpid();
138         for (fde=std_ev->ev->fd_events;fde;fde=fde->next) {
139                 epoll_add_event(std_ev, fde);
140         }
141 }
142
143 #define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT      (1<<0)
144 #define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR   (1<<1)
145 #define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR      (1<<2)
146
147 /*
148  add the epoll event to the given fd_event
149 */
150 static void epoll_add_event(struct std_event_context *std_ev, struct tevent_fd *fde)
151 {
152         struct epoll_event event;
153         if (std_ev->epoll_fd == -1) return;
154
155         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
156
157         /* if we don't want events yet, don't add an epoll_event */
158         if (fde->flags == 0) return;
159
160         ZERO_STRUCT(event);
161         event.events = epoll_map_flags(fde->flags);
162         event.data.ptr = fde;
163         if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
164                 epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
165         }
166         fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
167
168         /* only if we want to read we want to tell the event handler about errors */
169         if (fde->flags & TEVENT_FD_READ) {
170                 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
171         }
172 }
173
174 /*
175  delete the epoll event for given fd_event
176 */
177 static void epoll_del_event(struct std_event_context *std_ev, struct tevent_fd *fde)
178 {
179         struct epoll_event event;
180         if (std_ev->epoll_fd == -1) return;
181
182         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
183
184         /* if there's no epoll_event, we don't need to delete it */
185         if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
186
187         ZERO_STRUCT(event);
188         event.events = epoll_map_flags(fde->flags);
189         event.data.ptr = fde;
190         epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
191         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
192 }
193
194 /*
195  change the epoll event to the given fd_event
196 */
197 static void epoll_mod_event(struct std_event_context *std_ev, struct tevent_fd *fde)
198 {
199         struct epoll_event event;
200         if (std_ev->epoll_fd == -1) return;
201
202         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
203
204         ZERO_STRUCT(event);
205         event.events = epoll_map_flags(fde->flags);
206         event.data.ptr = fde;
207         if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
208                 epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
209         }
210
211         /* only if we want to read we want to tell the event handler about errors */
212         if (fde->flags & TEVENT_FD_READ) {
213                 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
214         }
215 }
216
217 static void epoll_change_event(struct std_event_context *std_ev, struct tevent_fd *fde)
218 {
219         bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
220         bool want_read = (fde->flags & TEVENT_FD_READ);
221         bool want_write= (fde->flags & TEVENT_FD_WRITE);
222
223         if (std_ev->epoll_fd == -1) return;
224
225         fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
226
227         /* there's already an event */
228         if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
229                 if (want_read || (want_write && !got_error)) {
230                         epoll_mod_event(std_ev, fde);
231                         return;
232                 }
233                 /* 
234                  * if we want to match the select behavior, we need to remove the epoll_event
235                  * when the caller isn't interested in events.
236                  *
237                  * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
238                  */
239                 epoll_del_event(std_ev, fde);
240                 return;
241         }
242
243         /* there's no epoll_event attached to the fde */
244         if (want_read || (want_write && !got_error)) {
245                 epoll_add_event(std_ev, fde);
246                 return;
247         }
248 }
249
250 /*
251   event loop handling using epoll
252 */
253 static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
254 {
255         int ret, i;
256 #define MAXEVENTS 8
257         struct epoll_event events[MAXEVENTS];
258         uint32_t destruction_count = ++std_ev->destruction_count;
259         int timeout = -1;
260
261         if (std_ev->epoll_fd == -1) return -1;
262
263         if (tvalp) {
264                 /* it's better to trigger timed events a bit later than to early */
265                 timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
266         }
267
268         if (std_ev->ev->signal_events &&
269             tevent_common_check_signal(std_ev->ev)) {
270                 return 0;
271         }
272
273         ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
274
275         if (ret == -1 && errno == EINTR && std_ev->ev->signal_events) {
276                 if (tevent_common_check_signal(std_ev->ev)) {
277                         return 0;
278                 }
279         }
280
281         if (ret == -1 && errno != EINTR) {
282                 epoll_fallback_to_select(std_ev, "epoll_wait() failed");
283                 return -1;
284         }
285
286         if (ret == 0 && tvalp) {
287                 /* we don't care about a possible delay here */
288                 tevent_common_loop_timer_delay(std_ev->ev);
289                 return 0;
290         }
291
292         for (i=0;i<ret;i++) {
293                 struct tevent_fd *fde = talloc_get_type(events[i].data.ptr, 
294                                                        struct tevent_fd);
295                 uint16_t flags = 0;
296
297                 if (fde == NULL) {
298                         epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
299                         return -1;
300                 }
301                 if (events[i].events & (EPOLLHUP|EPOLLERR)) {
302                         fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
303                         /*
304                          * if we only wait for TEVENT_FD_WRITE, we should not tell the
305                          * event handler about it, and remove the epoll_event,
306                          * as we only report errors when waiting for read events,
307                          * to match the select() behavior
308                          */
309                         if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
310                                 epoll_del_event(std_ev, fde);
311                                 continue;
312                         }
313                         flags |= TEVENT_FD_READ;
314                 }
315                 if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ;
316                 if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
317                 if (flags) {
318                         fde->handler(std_ev->ev, fde, flags, fde->private_data);
319                         if (destruction_count != std_ev->destruction_count) {
320                                 break;
321                         }
322                 }
323         }
324
325         return 0;
326 }
327 #else
328 #define epoll_init_ctx(std_ev) 
329 #define epoll_add_event(std_ev,fde)
330 #define epoll_del_event(std_ev,fde)
331 #define epoll_change_event(std_ev,fde)
332 #define epoll_event_loop(std_ev,tvalp) (-1)
333 #define epoll_check_reopen(std_ev)
334 #endif
335
336 /*
337   create a std_event_context structure.
338 */
339 static int std_event_context_init(struct tevent_context *ev)
340 {
341         struct std_event_context *std_ev;
342
343         std_ev = talloc_zero(ev, struct std_event_context);
344         if (!std_ev) return -1;
345         std_ev->ev = ev;
346         std_ev->epoll_fd = -1;
347
348         epoll_init_ctx(std_ev);
349
350         ev->additional_data = std_ev;
351         return 0;
352 }
353
354 /*
355   recalculate the maxfd
356 */
357 static void calc_maxfd(struct std_event_context *std_ev)
358 {
359         struct tevent_fd *fde;
360
361         std_ev->maxfd = 0;
362         for (fde = std_ev->ev->fd_events; fde; fde = fde->next) {
363                 if (fde->fd > std_ev->maxfd) {
364                         std_ev->maxfd = fde->fd;
365                 }
366         }
367 }
368
369
370 /* to mark the ev->maxfd invalid
371  * this means we need to recalculate it
372  */
373 #define EVENT_INVALID_MAXFD (-1)
374
375 /*
376   destroy an fd_event
377 */
378 static int std_event_fd_destructor(struct tevent_fd *fde)
379 {
380         struct tevent_context *ev = fde->event_ctx;
381         struct std_event_context *std_ev = NULL;
382
383         if (ev) {
384                 std_ev = talloc_get_type(ev->additional_data,
385                                          struct std_event_context);
386
387                 epoll_check_reopen(std_ev);
388
389                 if (std_ev->maxfd == fde->fd) {
390                         std_ev->maxfd = EVENT_INVALID_MAXFD;
391                 }
392
393                 std_ev->destruction_count++;
394
395                 epoll_del_event(std_ev, fde);
396         }
397
398         return tevent_common_fd_destructor(fde);
399 }
400
401 /*
402   add a fd based event
403   return NULL on failure (memory allocation error)
404 */
405 static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
406                                           int fd, uint16_t flags,
407                                           tevent_fd_handler_t handler,
408                                           void *private_data,
409                                           const char *handler_name,
410                                           const char *location)
411 {
412         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
413                                                            struct std_event_context);
414         struct tevent_fd *fde;
415
416         epoll_check_reopen(std_ev);
417
418         fde = tevent_common_add_fd(ev, mem_ctx, fd, flags,
419                                    handler, private_data,
420                                    handler_name, location);
421         if (!fde) return NULL;
422
423         if ((std_ev->maxfd != EVENT_INVALID_MAXFD)
424             && (fde->fd > std_ev->maxfd)) {
425                 std_ev->maxfd = fde->fd;
426         }
427         talloc_set_destructor(fde, std_event_fd_destructor);
428
429         epoll_add_event(std_ev, fde);
430
431         return fde;
432 }
433
434 /*
435   set the fd event flags
436 */
437 static void std_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
438 {
439         struct tevent_context *ev;
440         struct std_event_context *std_ev;
441
442         if (fde->flags == flags) return;
443
444         ev = fde->event_ctx;
445         std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
446
447         fde->flags = flags;
448
449         epoll_check_reopen(std_ev);
450
451         epoll_change_event(std_ev, fde);
452 }
453
454 /*
455   event loop handling using select()
456 */
457 static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
458 {
459         fd_set r_fds, w_fds;
460         struct tevent_fd *fde;
461         int selrtn;
462         uint32_t destruction_count = ++std_ev->destruction_count;
463
464         /* we maybe need to recalculate the maxfd */
465         if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
466                 calc_maxfd(std_ev);
467         }
468
469         FD_ZERO(&r_fds);
470         FD_ZERO(&w_fds);
471
472         /* setup any fd events */
473         for (fde = std_ev->ev->fd_events; fde; fde = fde->next) {
474                 if (fde->flags & TEVENT_FD_READ) {
475                         FD_SET(fde->fd, &r_fds);
476                 }
477                 if (fde->flags & TEVENT_FD_WRITE) {
478                         FD_SET(fde->fd, &w_fds);
479                 }
480         }
481
482         if (std_ev->ev->signal_events &&
483             tevent_common_check_signal(std_ev->ev)) {
484                 return 0;
485         }
486
487         selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
488
489         if (selrtn == -1 && errno == EINTR && 
490             std_ev->ev->signal_events) {
491                 tevent_common_check_signal(std_ev->ev);
492                 return 0;
493         }
494
495         if (selrtn == -1 && errno == EBADF) {
496                 /* the socket is dead! this should never
497                    happen as the socket should have first been
498                    made readable and that should have removed
499                    the event, so this must be a bug. This is a
500                    fatal error. */
501                 tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
502                              "ERROR: EBADF on std_event_loop_once\n");
503                 std_ev->exit_code = EBADF;
504                 return -1;
505         }
506
507         if (selrtn == 0 && tvalp) {
508                 /* we don't care about a possible delay here */
509                 tevent_common_loop_timer_delay(std_ev->ev);
510                 return 0;
511         }
512
513         if (selrtn > 0) {
514                 /* at least one file descriptor is ready - check
515                    which ones and call the handler, being careful to allow
516                    the handler to remove itself when called */
517                 for (fde = std_ev->ev->fd_events; fde; fde = fde->next) {
518                         uint16_t flags = 0;
519
520                         if (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
521                         if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
522                         if (flags) {
523                                 fde->handler(std_ev->ev, fde, flags, fde->private_data);
524                                 if (destruction_count != std_ev->destruction_count) {
525                                         break;
526                                 }
527                         }
528                 }
529         }
530
531         return 0;
532 }               
533
534 /*
535   do a single event loop using the events defined in ev 
536 */
537 static int std_event_loop_once(struct tevent_context *ev)
538 {
539         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
540                                                            struct std_event_context);
541         struct timeval tval;
542
543         tval = tevent_common_loop_timer_delay(ev);
544         if (ev_timeval_is_zero(&tval)) {
545                 return 0;
546         }
547
548         epoll_check_reopen(std_ev);
549
550         if (epoll_event_loop(std_ev, &tval) == 0) {
551                 return 0;
552         }
553
554         return std_event_loop_select(std_ev, &tval);
555 }
556
557 /*
558   return on failure or (with 0) if all fd events are removed
559 */
560 static int std_event_loop_wait(struct tevent_context *ev)
561 {
562         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
563                                                            struct std_event_context);
564         std_ev->exit_code = 0;
565
566         while (ev->fd_events && std_ev->exit_code == 0) {
567                 if (std_event_loop_once(ev) != 0) {
568                         break;
569                 }
570         }
571
572         return std_ev->exit_code;
573 }
574
575 static const struct tevent_ops std_event_ops = {
576         .context_init   = std_event_context_init,
577         .add_fd         = std_event_add_fd,
578         .set_fd_close_fn= tevent_common_fd_set_close_fn,
579         .get_fd_flags   = tevent_common_fd_get_flags,
580         .set_fd_flags   = std_event_set_fd_flags,
581         .add_timer      = tevent_common_add_timer,
582         .add_signal     = tevent_common_add_signal,
583         .loop_once      = std_event_loop_once,
584         .loop_wait      = std_event_loop_wait,
585 };
586
587
588 bool tevent_standard_init(void)
589 {
590         return tevent_register_backend("standard", &std_event_ops);
591 }
592