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