tevent: add tevent_fd_set_close_fn()
[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->close_fn) {
396                 fde->close_fn(ev, fde, fde->fd, fde->private_data);
397                 fde->fd = -1;
398         } else if (fde->flags & TEVENT_FD_AUTOCLOSE) {
399                 close(fde->fd);
400                 fde->fd = -1;
401         }
402
403         return 0;
404 }
405
406 /*
407   add a fd based event
408   return NULL on failure (memory allocation error)
409 */
410 static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
411                                           int fd, uint16_t flags,
412                                           tevent_fd_handler_t handler,
413                                           void *private_data,
414                                           const char *handler_name,
415                                           const char *location)
416 {
417         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
418                                                            struct std_event_context);
419         struct tevent_fd *fde;
420
421         epoll_check_reopen(std_ev);
422
423         fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
424         if (!fde) return NULL;
425
426         fde->event_ctx          = ev;
427         fde->fd                 = fd;
428         fde->flags              = flags;
429         fde->handler            = handler;
430         fde->private_data       = private_data;
431         fde->additional_flags   = 0;
432         fde->additional_data    = NULL;
433
434         DLIST_ADD(std_ev->fd_events, fde);
435         if ((std_ev->maxfd != EVENT_INVALID_MAXFD)
436             && (fde->fd > std_ev->maxfd)) {
437                 std_ev->maxfd = fde->fd;
438         }
439         talloc_set_destructor(fde, std_event_fd_destructor);
440
441         epoll_add_event(std_ev, fde);
442
443         return fde;
444 }
445
446 /*
447   set the fd event flags
448 */
449 static void std_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
450 {
451         struct tevent_context *ev;
452         struct std_event_context *std_ev;
453
454         if (fde->flags == flags) return;
455
456         ev = fde->event_ctx;
457         std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
458
459         fde->flags = flags;
460
461         epoll_check_reopen(std_ev);
462
463         epoll_change_event(std_ev, fde);
464 }
465
466 /*
467   event loop handling using select()
468 */
469 static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
470 {
471         fd_set r_fds, w_fds;
472         struct tevent_fd *fde;
473         int selrtn;
474         uint32_t destruction_count = ++std_ev->destruction_count;
475
476         /* we maybe need to recalculate the maxfd */
477         if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
478                 calc_maxfd(std_ev);
479         }
480
481         FD_ZERO(&r_fds);
482         FD_ZERO(&w_fds);
483
484         /* setup any fd events */
485         for (fde = std_ev->fd_events; fde; fde = fde->next) {
486                 if (fde->flags & TEVENT_FD_READ) {
487                         FD_SET(fde->fd, &r_fds);
488                 }
489                 if (fde->flags & TEVENT_FD_WRITE) {
490                         FD_SET(fde->fd, &w_fds);
491                 }
492         }
493
494         if (std_ev->ev->num_signal_handlers && 
495             tevent_common_check_signal(std_ev->ev)) {
496                 return 0;
497         }
498
499         selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
500
501         if (selrtn == -1 && errno == EINTR && 
502             std_ev->ev->num_signal_handlers) {
503                 tevent_common_check_signal(std_ev->ev);
504                 return 0;
505         }
506
507         if (selrtn == -1 && errno == EBADF) {
508                 /* the socket is dead! this should never
509                    happen as the socket should have first been
510                    made readable and that should have removed
511                    the event, so this must be a bug. This is a
512                    fatal error. */
513                 tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
514                              "ERROR: EBADF on std_event_loop_once\n");
515                 std_ev->exit_code = EBADF;
516                 return -1;
517         }
518
519         if (selrtn == 0 && tvalp) {
520                 /* we don't care about a possible delay here */
521                 tevent_common_loop_timer_delay(std_ev->ev);
522                 return 0;
523         }
524
525         if (selrtn > 0) {
526                 /* at least one file descriptor is ready - check
527                    which ones and call the handler, being careful to allow
528                    the handler to remove itself when called */
529                 for (fde = std_ev->fd_events; fde; fde = fde->next) {
530                         uint16_t flags = 0;
531
532                         if (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
533                         if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
534                         if (flags) {
535                                 fde->handler(std_ev->ev, fde, flags, fde->private_data);
536                                 if (destruction_count != std_ev->destruction_count) {
537                                         break;
538                                 }
539                         }
540                 }
541         }
542
543         return 0;
544 }               
545
546 /*
547   do a single event loop using the events defined in ev 
548 */
549 static int std_event_loop_once(struct tevent_context *ev)
550 {
551         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
552                                                            struct std_event_context);
553         struct timeval tval;
554
555         tval = tevent_common_loop_timer_delay(ev);
556         if (ev_timeval_is_zero(&tval)) {
557                 return 0;
558         }
559
560         epoll_check_reopen(std_ev);
561
562         if (epoll_event_loop(std_ev, &tval) == 0) {
563                 return 0;
564         }
565
566         return std_event_loop_select(std_ev, &tval);
567 }
568
569 /*
570   return on failure or (with 0) if all fd events are removed
571 */
572 static int std_event_loop_wait(struct tevent_context *ev)
573 {
574         struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
575                                                            struct std_event_context);
576         std_ev->exit_code = 0;
577
578         while (std_ev->fd_events && std_ev->exit_code == 0) {
579                 if (std_event_loop_once(ev) != 0) {
580                         break;
581                 }
582         }
583
584         return std_ev->exit_code;
585 }
586
587 static const struct tevent_ops std_event_ops = {
588         .context_init   = std_event_context_init,
589         .add_fd         = std_event_add_fd,
590         .set_fd_close_fn= tevent_common_fd_set_close_fn,
591         .get_fd_flags   = tevent_common_fd_get_flags,
592         .set_fd_flags   = std_event_set_fd_flags,
593         .add_timer      = tevent_common_add_timer,
594         .add_signal     = tevent_common_add_signal,
595         .loop_once      = std_event_loop_once,
596         .loop_wait      = std_event_loop_wait,
597 };
598
599
600 bool tevent_standard_init(void)
601 {
602         return tevent_register_backend("standard", &std_event_ops);
603 }
604