lib: tevent: Remove select backend.
[metze/samba/wip.git] / lib / tevent / tevent.c
1 /* 
2    Unix SMB/CIFS implementation.
3    main select loop and event handling
4    Copyright (C) Andrew Tridgell 2003
5    Copyright (C) Stefan Metzmacher 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   PLEASE READ THIS BEFORE MODIFYING!
27
28   This module is a general abstraction for the main select loop and
29   event handling. Do not ever put any localised hacks in here, instead
30   register one of the possible event types and implement that event
31   somewhere else.
32
33   There are 2 types of event handling that are handled in this module:
34
35   1) a file descriptor becoming readable or writeable. This is mostly
36      used for network sockets, but can be used for any type of file
37      descriptor. You may only register one handler for each file
38      descriptor/io combination or you will get unpredictable results
39      (this means that you can have a handler for read events, and a
40      separate handler for write events, but not two handlers that are
41      both handling read events)
42
43   2) a timed event. You can register an event that happens at a
44      specific time.  You can register as many of these as you
45      like. They are single shot - add a new timed event in the event
46      handler to get another event.
47
48   To setup a set of events you first need to create a event_context
49   structure using the function tevent_context_init(); This returns a
50   'struct tevent_context' that you use in all subsequent calls.
51
52   After that you can add/remove events that you are interested in
53   using tevent_add_*() and talloc_free()
54
55   Finally, you call tevent_loop_wait_once() to block waiting for one of the
56   events to occor or tevent_loop_wait() which will loop
57   forever.
58
59 */
60 #include "replace.h"
61 #include "system/filesys.h"
62 #ifdef HAVE_PTHREAD
63 #include "system/threads.h"
64 #endif
65 #define TEVENT_DEPRECATED 1
66 #include "tevent.h"
67 #include "tevent_internal.h"
68 #include "tevent_util.h"
69 #ifdef HAVE_EVENTFD
70 #include <sys/eventfd.h>
71 #endif
72
73 static void tevent_abort(struct tevent_context *ev, const char *reason);
74
75 struct tevent_ops_list {
76         struct tevent_ops_list *next, *prev;
77         const char *name;
78         const struct tevent_ops *ops;
79 };
80
81 /* list of registered event backends */
82 static struct tevent_ops_list *tevent_backends = NULL;
83 static char *tevent_default_backend = NULL;
84
85 /*
86   register an events backend
87 */
88 bool tevent_register_backend(const char *name, const struct tevent_ops *ops)
89 {
90         struct tevent_ops_list *e;
91
92         for (e = tevent_backends; e != NULL; e = e->next) {
93                 if (0 == strcmp(e->name, name)) {
94                         /* already registered, skip it */
95                         return true;
96                 }
97         }
98
99         e = talloc(NULL, struct tevent_ops_list);
100         if (e == NULL) return false;
101
102         e->name = name;
103         e->ops = ops;
104         DLIST_ADD(tevent_backends, e);
105
106         return true;
107 }
108
109 /*
110   set the default event backend
111  */
112 void tevent_set_default_backend(const char *backend)
113 {
114         talloc_free(tevent_default_backend);
115         tevent_default_backend = talloc_strdup(NULL, backend);
116 }
117
118 /*
119   initialise backends if not already done
120 */
121 static void tevent_backend_init(void)
122 {
123         static bool done;
124
125         if (done) {
126                 return;
127         }
128
129         done = true;
130
131         tevent_poll_init();
132         tevent_poll_mt_init();
133 #if defined(HAVE_EPOLL)
134         tevent_epoll_init();
135 #elif defined(HAVE_SOLARIS_PORTS)
136         tevent_port_init();
137 #endif
138
139         tevent_standard_init();
140 }
141
142 _PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name)
143 {
144         struct tevent_ops_list *e;
145
146         tevent_backend_init();
147
148         if (name == NULL) {
149                 name = tevent_default_backend;
150         }
151         if (name == NULL) {
152                 name = "standard";
153         }
154
155         for (e = tevent_backends; e != NULL; e = e->next) {
156                 if (0 == strcmp(e->name, name)) {
157                         return e->ops;
158                 }
159         }
160
161         return NULL;
162 }
163
164 /*
165   list available backends
166 */
167 const char **tevent_backend_list(TALLOC_CTX *mem_ctx)
168 {
169         const char **list = NULL;
170         struct tevent_ops_list *e;
171
172         tevent_backend_init();
173
174         for (e=tevent_backends;e;e=e->next) {
175                 list = ev_str_list_add(list, e->name);
176         }
177
178         talloc_steal(mem_ctx, list);
179
180         return list;
181 }
182
183 static void tevent_common_wakeup_fini(struct tevent_context *ev);
184
185 #ifdef HAVE_PTHREAD
186
187 static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER;
188 static struct tevent_context *tevent_contexts = NULL;
189 static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT;
190
191 static void tevent_atfork_prepare(void)
192 {
193         struct tevent_context *ev;
194         int ret;
195
196         ret = pthread_mutex_lock(&tevent_contexts_mutex);
197         if (ret != 0) {
198                 abort();
199         }
200
201         for (ev = tevent_contexts; ev != NULL; ev = ev->next) {
202                 struct tevent_threaded_context *tctx;
203
204                 for (tctx = ev->threaded_contexts; tctx != NULL;
205                      tctx = tctx->next) {
206                         ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
207                         if (ret != 0) {
208                                 tevent_abort(ev, "pthread_mutex_lock failed");
209                         }
210                 }
211
212                 ret = pthread_mutex_lock(&ev->scheduled_mutex);
213                 if (ret != 0) {
214                         tevent_abort(ev, "pthread_mutex_lock failed");
215                 }
216         }
217 }
218
219 static void tevent_atfork_parent(void)
220 {
221         struct tevent_context *ev;
222         int ret;
223
224         for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
225              ev = DLIST_PREV(ev)) {
226                 struct tevent_threaded_context *tctx;
227
228                 ret = pthread_mutex_unlock(&ev->scheduled_mutex);
229                 if (ret != 0) {
230                         tevent_abort(ev, "pthread_mutex_unlock failed");
231                 }
232
233                 for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL;
234                      tctx = DLIST_PREV(tctx)) {
235                         ret = pthread_mutex_unlock(&tctx->event_ctx_mutex);
236                         if (ret != 0) {
237                                 tevent_abort(
238                                         ev, "pthread_mutex_unlock failed");
239                         }
240                 }
241         }
242
243         ret = pthread_mutex_unlock(&tevent_contexts_mutex);
244         if (ret != 0) {
245                 abort();
246         }
247 }
248
249 static void tevent_atfork_child(void)
250 {
251         struct tevent_context *ev;
252         int ret;
253
254         for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
255              ev = DLIST_PREV(ev)) {
256                 struct tevent_threaded_context *tctx;
257
258                 for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL;
259                      tctx = DLIST_PREV(tctx)) {
260                         tctx->event_ctx = NULL;
261
262                         ret = pthread_mutex_unlock(&tctx->event_ctx_mutex);
263                         if (ret != 0) {
264                                 tevent_abort(
265                                         ev, "pthread_mutex_unlock failed");
266                         }
267                 }
268
269                 ev->threaded_contexts = NULL;
270
271                 ret = pthread_mutex_unlock(&ev->scheduled_mutex);
272                 if (ret != 0) {
273                         tevent_abort(ev, "pthread_mutex_unlock failed");
274                 }
275         }
276
277         ret = pthread_mutex_unlock(&tevent_contexts_mutex);
278         if (ret != 0) {
279                 abort();
280         }
281 }
282
283 static void tevent_prep_atfork(void)
284 {
285         int ret;
286
287         ret = pthread_atfork(tevent_atfork_prepare,
288                              tevent_atfork_parent,
289                              tevent_atfork_child);
290         if (ret != 0) {
291                 abort();
292         }
293 }
294
295 #endif
296
297 int tevent_common_context_destructor(struct tevent_context *ev)
298 {
299         struct tevent_fd *fd, *fn;
300         struct tevent_timer *te, *tn;
301         struct tevent_immediate *ie, *in;
302         struct tevent_signal *se, *sn;
303
304 #ifdef HAVE_PTHREAD
305         int ret;
306
307         ret = pthread_mutex_lock(&tevent_contexts_mutex);
308         if (ret != 0) {
309                 abort();
310         }
311
312         DLIST_REMOVE(tevent_contexts, ev);
313
314         ret = pthread_mutex_unlock(&tevent_contexts_mutex);
315         if (ret != 0) {
316                 abort();
317         }
318
319         while (ev->threaded_contexts != NULL) {
320                 struct tevent_threaded_context *tctx = ev->threaded_contexts;
321
322                 ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
323                 if (ret != 0) {
324                         abort();
325                 }
326
327                 /*
328                  * Indicate to the thread that the tevent_context is
329                  * gone. The counterpart of this is in
330                  * _tevent_threaded_schedule_immediate, there we read
331                  * this under the threaded_context's mutex.
332                  */
333
334                 tctx->event_ctx = NULL;
335
336                 ret = pthread_mutex_unlock(&tctx->event_ctx_mutex);
337                 if (ret != 0) {
338                         abort();
339                 }
340
341                 DLIST_REMOVE(ev->threaded_contexts, tctx);
342         }
343
344         ret = pthread_mutex_destroy(&ev->scheduled_mutex);
345         if (ret != 0) {
346                 abort();
347         }
348 #endif
349
350         tevent_common_wakeup_fini(ev);
351
352         for (fd = ev->fd_events; fd; fd = fn) {
353                 fn = fd->next;
354                 fd->event_ctx = NULL;
355                 DLIST_REMOVE(ev->fd_events, fd);
356         }
357
358         ev->last_zero_timer = NULL;
359         for (te = ev->timer_events; te; te = tn) {
360                 tn = te->next;
361                 te->event_ctx = NULL;
362                 DLIST_REMOVE(ev->timer_events, te);
363         }
364
365         for (ie = ev->immediate_events; ie; ie = in) {
366                 in = ie->next;
367                 ie->event_ctx = NULL;
368                 ie->cancel_fn = NULL;
369                 DLIST_REMOVE(ev->immediate_events, ie);
370         }
371
372         for (se = ev->signal_events; se; se = sn) {
373                 sn = se->next;
374                 se->event_ctx = NULL;
375                 DLIST_REMOVE(ev->signal_events, se);
376                 /*
377                  * This is important, Otherwise signals
378                  * are handled twice in child. eg, SIGHUP.
379                  * one added in parent, and another one in
380                  * the child. -- BoYang
381                  */
382                 tevent_cleanup_pending_signal_handlers(se);
383         }
384
385         /* removing nesting hook or we get an abort when nesting is
386          * not allowed. -- SSS
387          * Note that we need to leave the allowed flag at its current
388          * value, otherwise the use in tevent_re_initialise() will
389          * leave the event context with allowed forced to false, which
390          * will break users that expect nesting to be allowed
391          */
392         ev->nesting.level = 0;
393         ev->nesting.hook_fn = NULL;
394         ev->nesting.hook_private = NULL;
395
396         return 0;
397 }
398
399 static int tevent_common_context_constructor(struct tevent_context *ev)
400 {
401         int ret;
402
403 #ifdef HAVE_PTHREAD
404
405         ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork);
406         if (ret != 0) {
407                 return ret;
408         }
409
410         ret = pthread_mutex_init(&ev->scheduled_mutex, NULL);
411         if (ret != 0) {
412                 return ret;
413         }
414
415         ret = pthread_mutex_lock(&tevent_contexts_mutex);
416         if (ret != 0) {
417                 pthread_mutex_destroy(&ev->scheduled_mutex);
418                 return ret;
419         }
420
421         DLIST_ADD(tevent_contexts, ev);
422
423         ret = pthread_mutex_unlock(&tevent_contexts_mutex);
424         if (ret != 0) {
425                 abort();
426         }
427 #endif
428
429         talloc_set_destructor(ev, tevent_common_context_destructor);
430
431         return 0;
432 }
433
434 /*
435   create a event_context structure for a specific implemementation.
436   This must be the first events call, and all subsequent calls pass
437   this event_context as the first element. Event handlers also
438   receive this as their first argument.
439
440   This function is for allowing third-party-applications to hook in gluecode
441   to their own event loop code, so that they can make async usage of our client libs
442
443   NOTE: use tevent_context_init() inside of samba!
444 */
445 struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
446                                                const struct tevent_ops *ops,
447                                                void *additional_data)
448 {
449         struct tevent_context *ev;
450         int ret;
451
452         ev = talloc_zero(mem_ctx, struct tevent_context);
453         if (!ev) return NULL;
454
455         ret = tevent_common_context_constructor(ev);
456         if (ret != 0) {
457                 talloc_free(ev);
458                 return NULL;
459         }
460
461         ev->ops = ops;
462         ev->additional_data = additional_data;
463
464         ret = ev->ops->context_init(ev);
465         if (ret != 0) {
466                 talloc_free(ev);
467                 return NULL;
468         }
469
470         return ev;
471 }
472
473 /*
474   create a event_context structure. This must be the first events
475   call, and all subsequent calls pass this event_context as the first
476   element. Event handlers also receive this as their first argument.
477 */
478 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx,
479                                                   const char *name)
480 {
481         const struct tevent_ops *ops;
482
483         ops = tevent_find_ops_byname(name);
484         if (ops == NULL) {
485                 return NULL;
486         }
487
488         return tevent_context_init_ops(mem_ctx, ops, NULL);
489 }
490
491
492 /*
493   create a event_context structure. This must be the first events
494   call, and all subsequent calls pass this event_context as the first
495   element. Event handlers also receive this as their first argument.
496 */
497 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx)
498 {
499         return tevent_context_init_byname(mem_ctx, NULL);
500 }
501
502 /*
503   add a fd based event
504   return NULL on failure (memory allocation error)
505 */
506 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
507                                  TALLOC_CTX *mem_ctx,
508                                  int fd,
509                                  uint16_t flags,
510                                  tevent_fd_handler_t handler,
511                                  void *private_data,
512                                  const char *handler_name,
513                                  const char *location)
514 {
515         return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data,
516                                handler_name, location);
517 }
518
519 /*
520   set a close function on the fd event
521 */
522 void tevent_fd_set_close_fn(struct tevent_fd *fde,
523                             tevent_fd_close_fn_t close_fn)
524 {
525         if (!fde) return;
526         if (!fde->event_ctx) return;
527         fde->event_ctx->ops->set_fd_close_fn(fde, close_fn);
528 }
529
530 static void tevent_fd_auto_close_fn(struct tevent_context *ev,
531                                     struct tevent_fd *fde,
532                                     int fd,
533                                     void *private_data)
534 {
535         close(fd);
536 }
537
538 void tevent_fd_set_auto_close(struct tevent_fd *fde)
539 {
540         tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn);
541 }
542
543 /*
544   return the fd event flags
545 */
546 uint16_t tevent_fd_get_flags(struct tevent_fd *fde)
547 {
548         if (!fde) return 0;
549         if (!fde->event_ctx) return 0;
550         return fde->event_ctx->ops->get_fd_flags(fde);
551 }
552
553 /*
554   set the fd event flags
555 */
556 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
557 {
558         if (!fde) return;
559         if (!fde->event_ctx) return;
560         fde->event_ctx->ops->set_fd_flags(fde, flags);
561 }
562
563 bool tevent_signal_support(struct tevent_context *ev)
564 {
565         if (ev->ops->add_signal) {
566                 return true;
567         }
568         return false;
569 }
570
571 static void (*tevent_abort_fn)(const char *reason);
572
573 void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
574 {
575         tevent_abort_fn = abort_fn;
576 }
577
578 static void tevent_abort(struct tevent_context *ev, const char *reason)
579 {
580         tevent_debug(ev, TEVENT_DEBUG_FATAL,
581                      "abort: %s\n", reason);
582
583         if (!tevent_abort_fn) {
584                 abort();
585         }
586
587         tevent_abort_fn(reason);
588 }
589
590 /*
591   add a timer event
592   return NULL on failure
593 */
594 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
595                                        TALLOC_CTX *mem_ctx,
596                                        struct timeval next_event,
597                                        tevent_timer_handler_t handler,
598                                        void *private_data,
599                                        const char *handler_name,
600                                        const char *location)
601 {
602         return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data,
603                                   handler_name, location);
604 }
605
606 /*
607   allocate an immediate event
608   return NULL on failure (memory allocation error)
609 */
610 struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
611                                                   const char *location)
612 {
613         struct tevent_immediate *im;
614
615         im = talloc(mem_ctx, struct tevent_immediate);
616         if (im == NULL) return NULL;
617
618         *im = (struct tevent_immediate) { .create_location = location };
619
620         return im;
621 }
622
623 /*
624   schedule an immediate event
625 */
626 void _tevent_schedule_immediate(struct tevent_immediate *im,
627                                 struct tevent_context *ev,
628                                 tevent_immediate_handler_t handler,
629                                 void *private_data,
630                                 const char *handler_name,
631                                 const char *location)
632 {
633         ev->ops->schedule_immediate(im, ev, handler, private_data,
634                                     handler_name, location);
635 }
636
637 /*
638   add a signal event
639
640   sa_flags are flags to sigaction(2)
641
642   return NULL on failure
643 */
644 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
645                                          TALLOC_CTX *mem_ctx,
646                                          int signum,
647                                          int sa_flags,
648                                          tevent_signal_handler_t handler,
649                                          void *private_data,
650                                          const char *handler_name,
651                                          const char *location)
652 {
653         return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data,
654                                    handler_name, location);
655 }
656
657 void tevent_loop_allow_nesting(struct tevent_context *ev)
658 {
659         ev->nesting.allowed = true;
660 }
661
662 void tevent_loop_set_nesting_hook(struct tevent_context *ev,
663                                   tevent_nesting_hook hook,
664                                   void *private_data)
665 {
666         if (ev->nesting.hook_fn && 
667             (ev->nesting.hook_fn != hook ||
668              ev->nesting.hook_private != private_data)) {
669                 /* the way the nesting hook code is currently written
670                    we cannot support two different nesting hooks at the
671                    same time. */
672                 tevent_abort(ev, "tevent: Violation of nesting hook rules\n");
673         }
674         ev->nesting.hook_fn = hook;
675         ev->nesting.hook_private = private_data;
676 }
677
678 static void tevent_abort_nesting(struct tevent_context *ev, const char *location)
679 {
680         const char *reason;
681
682         reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s",
683                                  location);
684         if (!reason) {
685                 reason = "tevent_loop_once() nesting";
686         }
687
688         tevent_abort(ev, reason);
689 }
690
691 /*
692   do a single event loop using the events defined in ev 
693 */
694 int _tevent_loop_once(struct tevent_context *ev, const char *location)
695 {
696         int ret;
697         void *nesting_stack_ptr = NULL;
698
699         ev->nesting.level++;
700
701         if (ev->nesting.level > 1) {
702                 if (!ev->nesting.allowed) {
703                         tevent_abort_nesting(ev, location);
704                         errno = ELOOP;
705                         return -1;
706                 }
707         }
708         if (ev->nesting.level > 0) {
709                 if (ev->nesting.hook_fn) {
710                         int ret2;
711                         ret2 = ev->nesting.hook_fn(ev,
712                                                    ev->nesting.hook_private,
713                                                    ev->nesting.level,
714                                                    true,
715                                                    (void *)&nesting_stack_ptr,
716                                                    location);
717                         if (ret2 != 0) {
718                                 ret = ret2;
719                                 goto done;
720                         }
721                 }
722         }
723
724         tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE);
725         ret = ev->ops->loop_once(ev, location);
726         tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE);
727
728         if (ev->nesting.level > 0) {
729                 if (ev->nesting.hook_fn) {
730                         int ret2;
731                         ret2 = ev->nesting.hook_fn(ev,
732                                                    ev->nesting.hook_private,
733                                                    ev->nesting.level,
734                                                    false,
735                                                    (void *)&nesting_stack_ptr,
736                                                    location);
737                         if (ret2 != 0) {
738                                 ret = ret2;
739                                 goto done;
740                         }
741                 }
742         }
743
744 done:
745         ev->nesting.level--;
746         return ret;
747 }
748
749 /*
750   this is a performance optimization for the samba4 nested event loop problems
751 */
752 int _tevent_loop_until(struct tevent_context *ev,
753                        bool (*finished)(void *private_data),
754                        void *private_data,
755                        const char *location)
756 {
757         int ret = 0;
758         void *nesting_stack_ptr = NULL;
759
760         ev->nesting.level++;
761
762         if (ev->nesting.level > 1) {
763                 if (!ev->nesting.allowed) {
764                         tevent_abort_nesting(ev, location);
765                         errno = ELOOP;
766                         return -1;
767                 }
768         }
769         if (ev->nesting.level > 0) {
770                 if (ev->nesting.hook_fn) {
771                         int ret2;
772                         ret2 = ev->nesting.hook_fn(ev,
773                                                    ev->nesting.hook_private,
774                                                    ev->nesting.level,
775                                                    true,
776                                                    (void *)&nesting_stack_ptr,
777                                                    location);
778                         if (ret2 != 0) {
779                                 ret = ret2;
780                                 goto done;
781                         }
782                 }
783         }
784
785         while (!finished(private_data)) {
786                 tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE);
787                 ret = ev->ops->loop_once(ev, location);
788                 tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE);
789                 if (ret != 0) {
790                         break;
791                 }
792         }
793
794         if (ev->nesting.level > 0) {
795                 if (ev->nesting.hook_fn) {
796                         int ret2;
797                         ret2 = ev->nesting.hook_fn(ev,
798                                                    ev->nesting.hook_private,
799                                                    ev->nesting.level,
800                                                    false,
801                                                    (void *)&nesting_stack_ptr,
802                                                    location);
803                         if (ret2 != 0) {
804                                 ret = ret2;
805                                 goto done;
806                         }
807                 }
808         }
809
810 done:
811         ev->nesting.level--;
812         return ret;
813 }
814
815 bool tevent_common_have_events(struct tevent_context *ev)
816 {
817         if (ev->fd_events != NULL) {
818                 if (ev->fd_events != ev->wakeup_fde) {
819                         return true;
820                 }
821                 if (ev->fd_events->next != NULL) {
822                         return true;
823                 }
824
825                 /*
826                  * At this point we just have the wakeup pipe event as
827                  * the only fd_event. That one does not count as a
828                  * regular event, so look at the other event types.
829                  */
830         }
831
832         return ((ev->timer_events != NULL) ||
833                 (ev->immediate_events != NULL) ||
834                 (ev->signal_events != NULL));
835 }
836
837 /*
838   return on failure or (with 0) if all fd events are removed
839 */
840 int tevent_common_loop_wait(struct tevent_context *ev,
841                             const char *location)
842 {
843         /*
844          * loop as long as we have events pending
845          */
846         while (tevent_common_have_events(ev)) {
847                 int ret;
848                 ret = _tevent_loop_once(ev, location);
849                 if (ret != 0) {
850                         tevent_debug(ev, TEVENT_DEBUG_FATAL,
851                                      "_tevent_loop_once() failed: %d - %s\n",
852                                      ret, strerror(errno));
853                         return ret;
854                 }
855         }
856
857         tevent_debug(ev, TEVENT_DEBUG_WARNING,
858                      "tevent_common_loop_wait() out of events\n");
859         return 0;
860 }
861
862 /*
863   return on failure or (with 0) if all fd events are removed
864 */
865 int _tevent_loop_wait(struct tevent_context *ev, const char *location)
866 {
867         return ev->ops->loop_wait(ev, location);
868 }
869
870
871 /*
872   re-initialise a tevent context. This leaves you with the same
873   event context, but all events are wiped and the structure is
874   re-initialised. This is most useful after a fork()  
875
876   zero is returned on success, non-zero on failure
877 */
878 int tevent_re_initialise(struct tevent_context *ev)
879 {
880         tevent_common_context_destructor(ev);
881
882         tevent_common_context_constructor(ev);
883
884         return ev->ops->context_init(ev);
885 }
886
887 static void wakeup_pipe_handler(struct tevent_context *ev,
888                                 struct tevent_fd *fde,
889                                 uint16_t flags, void *_private)
890 {
891         ssize_t ret;
892
893         do {
894                 /*
895                  * This is the boilerplate for eventfd, but it works
896                  * for pipes too. And as we don't care about the data
897                  * we read, we're fine.
898                  */
899                 uint64_t val;
900                 ret = read(fde->fd, &val, sizeof(val));
901         } while (ret == -1 && errno == EINTR);
902 }
903
904 /*
905  * Initialize the wakeup pipe and pipe fde
906  */
907
908 int tevent_common_wakeup_init(struct tevent_context *ev)
909 {
910         int ret, read_fd;
911
912         if (ev->wakeup_fde != NULL) {
913                 return 0;
914         }
915
916 #ifdef HAVE_EVENTFD
917         ret = eventfd(0, EFD_NONBLOCK);
918         if (ret == -1) {
919                 return errno;
920         }
921         read_fd = ev->wakeup_fd = ret;
922 #else
923         {
924                 int pipe_fds[2];
925                 ret = pipe(pipe_fds);
926                 if (ret == -1) {
927                         return errno;
928                 }
929                 ev->wakeup_fd = pipe_fds[1];
930                 ev->wakeup_read_fd = pipe_fds[0];
931
932                 ev_set_blocking(ev->wakeup_fd, false);
933                 ev_set_blocking(ev->wakeup_read_fd, false);
934
935                 read_fd = ev->wakeup_read_fd;
936         }
937 #endif
938
939         ev->wakeup_fde = tevent_add_fd(ev, ev, read_fd, TEVENT_FD_READ,
940                                      wakeup_pipe_handler, NULL);
941         if (ev->wakeup_fde == NULL) {
942                 close(ev->wakeup_fd);
943 #ifndef HAVE_EVENTFD
944                 close(ev->wakeup_read_fd);
945 #endif
946                 return ENOMEM;
947         }
948
949         return 0;
950 }
951
952 int tevent_common_wakeup_fd(int fd)
953 {
954         ssize_t ret;
955
956         do {
957 #ifdef HAVE_EVENTFD
958                 uint64_t val = 1;
959                 ret = write(fd, &val, sizeof(val));
960 #else
961                 char c = '\0';
962                 ret = write(fd, &c, 1);
963 #endif
964         } while ((ret == -1) && (errno == EINTR));
965
966         return 0;
967 }
968
969 int tevent_common_wakeup(struct tevent_context *ev)
970 {
971         if (ev->wakeup_fde == NULL) {
972                 return ENOTCONN;
973         }
974
975         return tevent_common_wakeup_fd(ev->wakeup_fd);
976 }
977
978 static void tevent_common_wakeup_fini(struct tevent_context *ev)
979 {
980         if (ev->wakeup_fde == NULL) {
981                 return;
982         }
983
984         TALLOC_FREE(ev->wakeup_fde);
985
986         close(ev->wakeup_fd);
987 #ifndef HAVE_EVENTFD
988         close(ev->wakeup_read_fd);
989 #endif
990 }