Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
[metze/samba/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
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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20
21 /*
22   This is SAMBA's default event loop code
23
24   - we try to use epoll if configure detected support for it
25     otherwise we use select()
26   - if epoll is broken on the system or the kernel doesn't support it
27     at runtime we fallback to select()
28 */
29
30 #include "replace.h"
31 #include "system/filesys.h"
32 #include "system/network.h"
33 #include "system/select.h"
34 #include "tevent.h"
35 #include "tevent_util.h"
36 #include "tevent_internal.h"
37
38 struct std_event_context {
39         /* a pointer back to the generic event_context */
40         struct tevent_context *ev;
41
42         /* list of filedescriptor events */
43         struct tevent_fd *fd_events;
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->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->num_signal_handlers && 
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->num_signal_handlers) {
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->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 = talloc_get_type(ev->additional_data,
382                                                            struct std_event_context);
383
384         epoll_check_reopen(std_ev);
385
386         if (std_ev->maxfd == fde->fd) {
387                 std_ev->maxfd = EVENT_INVALID_MAXFD;
388         }
389
390         DLIST_REMOVE(std_ev->fd_events, fde);
391         std_ev->destruction_count++;
392
393         epoll_del_event(std_ev, fde);
394
395         if (fde->flags & TEVENT_FD_AUTOCLOSE) {
396                 close(fde->fd);
397                 fde->fd = -1;
398         }
399
400         return 0;
401 }
402
403 /*
404   add a fd based event
405   return NULL on failure (memory allocation error)
406 */
407 static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
408                                           int fd, uint16_t flags,
409                                           tevent_fd_handler_t handler,
410                                           void *private_data,
411                                           const char *handler_name,
412                                           const char *location)
413 {
414         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
415                                                            struct std_event_context);
416         struct tevent_fd *fde;
417
418         epoll_check_reopen(std_ev);
419
420         fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
421         if (!fde) return NULL;
422
423         fde->event_ctx          = ev;
424         fde->fd                 = fd;
425         fde->flags              = flags;
426         fde->handler            = handler;
427         fde->private_data       = private_data;
428         fde->additional_flags   = 0;
429         fde->additional_data    = NULL;
430
431         DLIST_ADD(std_ev->fd_events, fde);
432         if ((std_ev->maxfd != EVENT_INVALID_MAXFD)
433             && (fde->fd > std_ev->maxfd)) {
434                 std_ev->maxfd = fde->fd;
435         }
436         talloc_set_destructor(fde, std_event_fd_destructor);
437
438         epoll_add_event(std_ev, fde);
439
440         return fde;
441 }
442
443
444 /*
445   return the fd event flags
446 */
447 static uint16_t std_event_get_fd_flags(struct tevent_fd *fde)
448 {
449         return fde->flags;
450 }
451
452 /*
453   set the fd event flags
454 */
455 static void std_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
456 {
457         struct tevent_context *ev;
458         struct std_event_context *std_ev;
459
460         if (fde->flags == flags) return;
461
462         ev = fde->event_ctx;
463         std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
464
465         fde->flags = flags;
466
467         epoll_check_reopen(std_ev);
468
469         epoll_change_event(std_ev, fde);
470 }
471
472 /*
473   event loop handling using select()
474 */
475 static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
476 {
477         fd_set r_fds, w_fds;
478         struct tevent_fd *fde;
479         int selrtn;
480         uint32_t destruction_count = ++std_ev->destruction_count;
481
482         /* we maybe need to recalculate the maxfd */
483         if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
484                 calc_maxfd(std_ev);
485         }
486
487         FD_ZERO(&r_fds);
488         FD_ZERO(&w_fds);
489
490         /* setup any fd events */
491         for (fde = std_ev->fd_events; fde; fde = fde->next) {
492                 if (fde->flags & TEVENT_FD_READ) {
493                         FD_SET(fde->fd, &r_fds);
494                 }
495                 if (fde->flags & TEVENT_FD_WRITE) {
496                         FD_SET(fde->fd, &w_fds);
497                 }
498         }
499
500         if (std_ev->ev->num_signal_handlers && 
501             tevent_common_check_signal(std_ev->ev)) {
502                 return 0;
503         }
504
505         selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
506
507         if (selrtn == -1 && errno == EINTR && 
508             std_ev->ev->num_signal_handlers) {
509                 tevent_common_check_signal(std_ev->ev);
510                 return 0;
511         }
512
513         if (selrtn == -1 && errno == EBADF) {
514                 /* the socket is dead! this should never
515                    happen as the socket should have first been
516                    made readable and that should have removed
517                    the event, so this must be a bug. This is a
518                    fatal error. */
519                 tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
520                              "ERROR: EBADF on std_event_loop_once\n");
521                 std_ev->exit_code = EBADF;
522                 return -1;
523         }
524
525         if (selrtn == 0 && tvalp) {
526                 /* we don't care about a possible delay here */
527                 tevent_common_loop_timer_delay(std_ev->ev);
528                 return 0;
529         }
530
531         if (selrtn > 0) {
532                 /* at least one file descriptor is ready - check
533                    which ones and call the handler, being careful to allow
534                    the handler to remove itself when called */
535                 for (fde = std_ev->fd_events; fde; fde = fde->next) {
536                         uint16_t flags = 0;
537
538                         if (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
539                         if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
540                         if (flags) {
541                                 fde->handler(std_ev->ev, fde, flags, fde->private_data);
542                                 if (destruction_count != std_ev->destruction_count) {
543                                         break;
544                                 }
545                         }
546                 }
547         }
548
549         return 0;
550 }               
551
552 /*
553   do a single event loop using the events defined in ev 
554 */
555 static int std_event_loop_once(struct tevent_context *ev)
556 {
557         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
558                                                            struct std_event_context);
559         struct timeval tval;
560
561         tval = tevent_common_loop_timer_delay(ev);
562         if (ev_timeval_is_zero(&tval)) {
563                 return 0;
564         }
565
566         epoll_check_reopen(std_ev);
567
568         if (epoll_event_loop(std_ev, &tval) == 0) {
569                 return 0;
570         }
571
572         return std_event_loop_select(std_ev, &tval);
573 }
574
575 /*
576   return on failure or (with 0) if all fd events are removed
577 */
578 static int std_event_loop_wait(struct tevent_context *ev)
579 {
580         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
581                                                            struct std_event_context);
582         std_ev->exit_code = 0;
583
584         while (std_ev->fd_events && std_ev->exit_code == 0) {
585                 if (std_event_loop_once(ev) != 0) {
586                         break;
587                 }
588         }
589
590         return std_ev->exit_code;
591 }
592
593 static const struct tevent_ops std_event_ops = {
594         .context_init   = std_event_context_init,
595         .add_fd         = std_event_add_fd,
596         .get_fd_flags   = std_event_get_fd_flags,
597         .set_fd_flags   = std_event_set_fd_flags,
598         .add_timer      = tevent_common_add_timer,
599         .add_signal     = tevent_common_add_signal,
600         .loop_once      = std_event_loop_once,
601         .loop_wait      = std_event_loop_wait,
602 };
603
604
605 bool tevent_standard_init(void)
606 {
607         return tevent_register_backend("standard", &std_event_ops);
608 }
609