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