s4/torture: Fix misplaced positional arguments for u64 comparison
[gd/samba-autobuild/.git] / lib / tevent / tevent_internal.h
1 /*
2    Unix SMB/CIFS implementation.
3
4    generalised event loop handling
5
6    INTERNAL STRUCTS. THERE ARE NO API GUARANTEES.
7    External users should only ever have to include this header when
8    implementing new tevent backends.
9
10    Copyright (C) Stefan Metzmacher 2005-2009
11
12      ** NOTE! The following LGPL license applies to the tevent
13      ** library. This does NOT imply that all of Samba is released
14      ** under the LGPL
15
16    This library is free software; you can redistribute it and/or
17    modify it under the terms of the GNU Lesser General Public
18    License as published by the Free Software Foundation; either
19    version 3 of the License, or (at your option) any later version.
20
21    This library is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24    Lesser General Public License for more details.
25
26    You should have received a copy of the GNU Lesser General Public
27    License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 */
29
30 struct tevent_req {
31         /**
32          * @brief What to do on completion
33          *
34          * This is used for the user of an async request, fn is called when
35          * the request completes, either successfully or with an error.
36          */
37         struct {
38                 /**
39                  * @brief Completion function
40                  * Completion function, to be filled by the API user
41                  */
42                 tevent_req_fn fn;
43                 /**
44                  * @brief Private data for the completion function
45                  */
46                 void *private_data;
47                 /**
48                  * @brief  The completion function name, for flow tracing.
49                  */
50                 const char *fn_name;
51         } async;
52
53         /**
54          * @brief Private state pointer for the actual implementation
55          *
56          * The implementation doing the work for the async request needs to
57          * keep around current data like for example a fd event. The user of
58          * an async request should not touch this.
59          */
60         void *data;
61
62         /**
63          * @brief A function to overwrite the default print function
64          *
65          * The implementation doing the work may want to implement a
66          * custom function to print the text representation of the async
67          * request.
68          */
69         tevent_req_print_fn private_print;
70
71         /**
72          * @brief A function to cancel the request
73          *
74          * The implementation might want to set a function
75          * that is called when the tevent_req_cancel() function
76          * was called.
77          */
78         struct {
79                 tevent_req_cancel_fn fn;
80                 const char *fn_name;
81         } private_cancel;
82
83         /**
84          * @brief A function to cleanup the request
85          *
86          * The implementation might want to set a function
87          * that is called before the tevent_req_done() and tevent_req_error()
88          * trigger the callers callback function.
89          */
90         struct {
91                 tevent_req_cleanup_fn fn;
92                 const char *fn_name;
93                 enum tevent_req_state state;
94         } private_cleanup;
95
96         /**
97          * @brief Internal state of the request
98          *
99          * Callers should only access this via functions and never directly.
100          */
101         struct {
102                 /**
103                  * @brief The talloc type of the data pointer
104                  *
105                  * This is filled by the tevent_req_create() macro.
106                  *
107                  * This for debugging only.
108                  */
109                 const char *private_type;
110
111                 /**
112                  * @brief The location where the request was created
113                  *
114                  * This uses the __location__ macro via the tevent_req_create()
115                  * macro.
116                  *
117                  * This for debugging only.
118                  */
119                 const char *create_location;
120
121                 /**
122                  * @brief The location where the request was finished
123                  *
124                  * This uses the __location__ macro via the tevent_req_done(),
125                  * tevent_req_error() or tevent_req_nomem() macro.
126                  *
127                  * This for debugging only.
128                  */
129                 const char *finish_location;
130
131                 /**
132                  * @brief The location where the request was canceled
133                  *
134                  * This uses the __location__ macro via the
135                  * tevent_req_cancel() macro.
136                  *
137                  * This for debugging only.
138                  */
139                 const char *cancel_location;
140
141                 /**
142                  * @brief The external state - will be queried by the caller
143                  *
144                  * While the async request is being processed, state will remain in
145                  * TEVENT_REQ_IN_PROGRESS. A request is finished if
146                  * req->state>=TEVENT_REQ_DONE.
147                  */
148                 enum tevent_req_state state;
149
150                 /**
151                  * @brief status code when finished
152                  *
153                  * This status can be queried in the async completion function. It
154                  * will be set to 0 when everything went fine.
155                  */
156                 uint64_t error;
157
158                 /**
159                  * @brief the immediate event used by tevent_req_post
160                  *
161                  */
162                 struct tevent_immediate *trigger;
163
164                 /**
165                  * @brief An event context which will be used to
166                  *        defer the _tevent_req_notify_callback().
167                  */
168                 struct tevent_context *defer_callback_ev;
169
170                 /**
171                  * @brief the timer event if tevent_req_set_endtime was used
172                  *
173                  */
174                 struct tevent_timer *timer;
175
176                 /**
177                  * @brief The place where profiling data is kept
178                  */
179                 struct tevent_req_profile *profile;
180
181                 size_t call_depth;
182         } internal;
183 };
184
185 struct tevent_req_profile {
186         struct tevent_req_profile *prev, *next;
187         struct tevent_req_profile *parent;
188         const char *req_name;
189         pid_t pid;
190         const char *start_location;
191         struct timeval start_time;
192         const char *stop_location;
193         struct timeval stop_time;
194         enum tevent_req_state state;
195         uint64_t user_error;
196         struct tevent_req_profile *subprofiles;
197 };
198
199 struct tevent_fd {
200         struct tevent_fd *prev, *next;
201         struct tevent_context *event_ctx;
202         struct tevent_wrapper_glue *wrapper;
203         bool busy;
204         bool destroyed;
205         int fd;
206         uint16_t flags; /* see TEVENT_FD_* flags */
207         tevent_fd_handler_t handler;
208         tevent_fd_close_fn_t close_fn;
209         /* this is private for the specific handler */
210         void *private_data;
211         /* this is for debugging only! */
212         const char *handler_name;
213         const char *location;
214         /* this is private for the events_ops implementation */
215         uint64_t additional_flags;
216         void *additional_data;
217         /* custom tag that can be set by caller */
218         uint64_t tag;
219         struct tevent_fd_mpx {
220                 struct tevent_fd_mpx *prev, *next;
221                 struct tevent_fd *fde;
222                 struct tevent_fd *primary;
223                 struct tevent_fd_mpx *list;
224                 uint16_t total_flags;
225                 bool has_mpx;
226         } mpx;
227 };
228
229 struct tevent_timer {
230         struct tevent_timer *prev, *next;
231         struct tevent_context *event_ctx;
232         struct tevent_wrapper_glue *wrapper;
233         bool busy;
234         bool destroyed;
235         struct timeval next_event;
236         tevent_timer_handler_t handler;
237         /* this is private for the specific handler */
238         void *private_data;
239         /* this is for debugging only! */
240         const char *handler_name;
241         const char *location;
242         /* this is private for the events_ops implementation */
243         void *additional_data;
244         /* custom tag that can be set by caller */
245         uint64_t tag;
246 };
247
248 struct tevent_immediate {
249         struct tevent_immediate *prev, *next;
250         struct tevent_context *event_ctx;
251         struct tevent_wrapper_glue *wrapper;
252         bool busy;
253         bool destroyed;
254         struct tevent_context *detach_ev_ctx;
255         tevent_immediate_handler_t handler;
256         /* this is private for the specific handler */
257         void *private_data;
258         /* this is for debugging only! */
259         const char *handler_name;
260         const char *create_location;
261         const char *schedule_location;
262         /* this is private for the events_ops implementation */
263         void (*cancel_fn)(struct tevent_immediate *im);
264         void *additional_data;
265         /* custom tag that can be set by caller */
266         uint64_t tag;
267 };
268
269 struct tevent_signal {
270         struct tevent_signal *prev, *next;
271         struct tevent_context *event_ctx;
272         struct tevent_wrapper_glue *wrapper;
273         bool busy;
274         bool destroyed;
275         int signum;
276         int sa_flags;
277         tevent_signal_handler_t handler;
278         /* this is private for the specific handler */
279         void *private_data;
280         /* this is for debugging only! */
281         const char *handler_name;
282         const char *location;
283         /* this is private for the events_ops implementation */
284         void *additional_data;
285         /* custom tag that can be set by caller */
286         uint64_t tag;
287 };
288
289 struct tevent_threaded_context {
290         struct tevent_threaded_context *next, *prev;
291
292 #ifdef HAVE_PTHREAD
293         pthread_mutex_t event_ctx_mutex;
294 #endif
295         struct tevent_context *event_ctx;
296 };
297
298 struct tevent_debug_ops {
299         enum tevent_debug_level max_level;
300         void (*debug)(void *context, enum tevent_debug_level level,
301                       const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
302         void *context;
303 };
304
305 void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
306                   const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
307 #define TEVENT_DEBUG(__ev, __level, __fmt, ...) do { \
308         if (unlikely((__ev) != NULL && \
309                      (__level) <= (__ev)->debug_ops.max_level)) \
310         { \
311                 tevent_debug((__ev), (__level), (__fmt), __VA_ARGS__); \
312         } \
313 } while(0)
314
315 void tevent_abort(struct tevent_context *ev, const char *reason);
316
317 void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason);
318
319 struct tevent_context {
320         /* the specific events implementation */
321         const struct tevent_ops *ops;
322
323         /*
324          * The following three pointers are queried on every loop_once
325          * in the order in which they appear here. Not measured, but
326          * hopefully putting them at the top together with "ops"
327          * should make tevent a *bit* more cache-friendly than before.
328          */
329
330         /* list of signal events - used by common code */
331         struct tevent_signal *signal_events;
332
333         /* List of threaded job indicators */
334         struct tevent_threaded_context *threaded_contexts;
335
336         /* list of immediate events - used by common code */
337         struct tevent_immediate *immediate_events;
338
339         /* list of fd events - used by common code */
340         struct tevent_fd *fd_events;
341
342         /* list of timed events - used by common code */
343         struct tevent_timer *timer_events;
344
345         /* List of scheduled immediates */
346         pthread_mutex_t scheduled_mutex;
347         struct tevent_immediate *scheduled_immediates;
348
349         /* this is private for the events_ops implementation */
350         void *additional_data;
351
352         /* pipe hack used with signal handlers */
353         struct tevent_fd *wakeup_fde;
354         int wakeup_fd;          /* fd to write into */
355 #ifndef HAVE_EVENT_FD
356         int wakeup_read_fd;
357 #endif
358
359         /* debugging operations */
360         struct tevent_debug_ops debug_ops;
361
362         /* info about the nesting status */
363         struct {
364                 bool allowed;
365                 uint32_t level;
366                 tevent_nesting_hook hook_fn;
367                 void *hook_private;
368         } nesting;
369
370         struct {
371                 struct {
372                         tevent_trace_callback_t callback;
373                         void *private_data;
374                 } point;
375
376                 struct {
377                         tevent_trace_fd_callback_t callback;
378                         void *private_data;
379                 } fde;
380
381                 struct {
382                         tevent_trace_signal_callback_t callback;
383                         void *private_data;
384                 } se;
385
386                 struct {
387                         tevent_trace_timer_callback_t callback;
388                         void *private_data;
389                 } te;
390
391                 struct {
392                         tevent_trace_immediate_callback_t callback;
393                         void *private_data;
394                 } im;
395
396                 struct {
397                         tevent_trace_queue_callback_t callback;
398                         void *private_data;
399                 } qe;
400         } tracing;
401
402         struct {
403                 /*
404                  * This is used on the main event context
405                  */
406                 struct tevent_wrapper_glue *list;
407
408                 /*
409                  * This is used on the wrapper event context
410                  */
411                 struct tevent_wrapper_glue *glue;
412         } wrapper;
413
414         /*
415          * an optimization pointer into timer_events
416          * used by used by common code via
417          * tevent_common_add_timer_v2()
418          */
419         struct tevent_timer *last_zero_timer;
420
421 #ifdef HAVE_PTHREAD
422         struct tevent_context *prev, *next;
423 #endif
424 };
425
426 int tevent_common_context_destructor(struct tevent_context *ev);
427 int tevent_common_loop_wait(struct tevent_context *ev,
428                             const char *location);
429
430 struct tevent_common_fd_buf {
431         char buf[128];
432 };
433
434 const char *tevent_common_fd_str(struct tevent_common_fd_buf *buf,
435                                  const char *description,
436                                  const struct tevent_fd *fde);
437
438 int tevent_common_fd_destructor(struct tevent_fd *fde);
439 struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev,
440                                        TALLOC_CTX *mem_ctx,
441                                        int fd,
442                                        uint16_t flags,
443                                        tevent_fd_handler_t handler,
444                                        void *private_data,
445                                        const char *handler_name,
446                                        const char *location);
447 void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
448                                    tevent_fd_close_fn_t close_fn);
449 uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
450 void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
451 int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
452                                     bool *removed);
453
454 struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
455                                              TALLOC_CTX *mem_ctx,
456                                              struct timeval next_event,
457                                              tevent_timer_handler_t handler,
458                                              void *private_data,
459                                              const char *handler_name,
460                                              const char *location);
461 struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev,
462                                                 TALLOC_CTX *mem_ctx,
463                                                 struct timeval next_event,
464                                                 tevent_timer_handler_t handler,
465                                                 void *private_data,
466                                                 const char *handler_name,
467                                                 const char *location);
468 struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
469 int tevent_common_invoke_timer_handler(struct tevent_timer *te,
470                                        struct timeval current_time,
471                                        bool *removed);
472
473 void tevent_common_schedule_immediate(struct tevent_immediate *im,
474                                       struct tevent_context *ev,
475                                       tevent_immediate_handler_t handler,
476                                       void *private_data,
477                                       const char *handler_name,
478                                       const char *location);
479 int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
480                                            bool *removed);
481 bool tevent_common_loop_immediate(struct tevent_context *ev);
482 void tevent_common_threaded_activate_immediate(struct tevent_context *ev);
483
484 bool tevent_common_have_events(struct tevent_context *ev);
485 int tevent_common_wakeup_init(struct tevent_context *ev);
486 int tevent_common_wakeup_fd(int fd);
487 int tevent_common_wakeup(struct tevent_context *ev);
488
489 struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
490                                                TALLOC_CTX *mem_ctx,
491                                                int signum,
492                                                int sa_flags,
493                                                tevent_signal_handler_t handler,
494                                                void *private_data,
495                                                const char *handler_name,
496                                                const char *location);
497 int tevent_common_check_signal(struct tevent_context *ev);
498 void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se);
499 int tevent_common_invoke_signal_handler(struct tevent_signal *se,
500                                         int signum, int count, void *siginfo,
501                                         bool *removed);
502
503 struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev);
504
505 struct tevent_wrapper_ops;
506
507 struct tevent_wrapper_glue {
508         struct tevent_wrapper_glue *prev, *next;
509         struct tevent_context *wrap_ev;
510         struct tevent_context *main_ev;
511         bool busy;
512         bool destroyed;
513         const struct tevent_wrapper_ops *ops;
514         void *private_state;
515 };
516
517 void tevent_wrapper_push_use_internal(struct tevent_context *ev,
518                                       struct tevent_wrapper_glue *wrapper);
519 void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr,
520                                      struct tevent_wrapper_glue *wrapper);
521
522 bool tevent_standard_init(void);
523 bool tevent_poll_init(void);
524 bool tevent_poll_event_add_fd_internal(struct tevent_context *ev,
525                                        struct tevent_fd *fde);
526 bool tevent_poll_mt_init(void);
527 #ifdef HAVE_EPOLL
528 bool tevent_epoll_init(void);
529 void tevent_epoll_set_panic_fallback(struct tevent_context *ev,
530                         bool (*panic_fallback)(struct tevent_context *ev,
531                                                bool replay));
532 #endif
533
534 static inline void tevent_thread_call_depth_notify(
535                         enum tevent_thread_call_depth_cmd cmd,
536                         struct tevent_req *req,
537                         size_t depth,
538                         const char *fname)
539 {
540         if (tevent_thread_call_depth_state_g.cb != NULL) {
541                 tevent_thread_call_depth_state_g.cb(
542                         tevent_thread_call_depth_state_g.cb_private,
543                         cmd,
544                         req,
545                         depth,
546                         fname);
547         }
548 }
549
550 void tevent_trace_point_callback(struct tevent_context *ev,
551                                  enum tevent_trace_point);
552
553 void tevent_trace_fd_callback(struct tevent_context *ev,
554                               struct tevent_fd *fde,
555                               enum tevent_event_trace_point);
556
557 void tevent_trace_signal_callback(struct tevent_context *ev,
558                                   struct tevent_signal *se,
559                                   enum tevent_event_trace_point);
560
561 void tevent_trace_timer_callback(struct tevent_context *ev,
562                                  struct tevent_timer *te,
563                                  enum tevent_event_trace_point);
564
565 void tevent_trace_immediate_callback(struct tevent_context *ev,
566                                      struct tevent_immediate *im,
567                                      enum tevent_event_trace_point);
568
569 void tevent_trace_queue_callback(struct tevent_context *ev,
570                                  struct tevent_queue_entry *qe,
571                                  enum tevent_event_trace_point);
572
573 #include "tevent_dlinklist.h"
574
575 static inline void tevent_common_fd_mpx_reinit(struct tevent_fd *fde)
576 {
577         fde->mpx = (struct tevent_fd_mpx) { .fde = fde, };
578 }
579
580 static inline void tevent_common_fd_disarm(struct tevent_fd *fde)
581 {
582         if (fde->event_ctx != NULL) {
583                 tevent_trace_fd_callback(fde->event_ctx, fde,
584                                          TEVENT_EVENT_TRACE_DETACH);
585                 DLIST_REMOVE(fde->event_ctx->fd_events, fde);
586                 fde->event_ctx = NULL;
587         }
588         tevent_common_fd_mpx_reinit(fde);
589         fde->wrapper = NULL;
590 }
591
592 /*
593  * tevent_common_fd_mpx_primary() returns the fde that is responsible
594  * for the low level state.
595  *
596  * By default (when there's no multiplexing) it just returns 'any_fde'.
597  *
598  * Note it always returns a valid pointer.
599  */
600 static inline
601 struct tevent_fd *tevent_common_fd_mpx_primary(struct tevent_fd *any_fde)
602 {
603         struct tevent_fd *primary = NULL;
604
605         if (any_fde->mpx.primary != NULL) {
606                 primary = any_fde->mpx.primary;
607         } else {
608                 primary = any_fde;
609         }
610
611         return primary;
612 }
613
614 /*
615  * tevent_common_fd_mpx_update_flags() needs to be called
616  * if update_fde->flags has changed. It is needed in
617  * order to let tevent_common_fd_mpx_flags() return a valid
618  * result.
619  */
620 static inline
621 void tevent_common_fd_mpx_update_flags(struct tevent_fd *update_fde)
622 {
623         struct tevent_fd *primary = tevent_common_fd_mpx_primary(update_fde);
624         struct tevent_fd_mpx *mpx = NULL;
625         uint16_t new_total_flags = 0;
626
627         if (!primary->mpx.has_mpx) {
628                 primary->mpx.total_flags = primary->flags;
629                 return;
630         }
631
632         for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
633                 struct tevent_fd *mpx_fde = mpx->fde;
634                 /* we don't care that mpx_fde might be == primary */
635                 new_total_flags |= mpx_fde->flags;
636         }
637
638         primary->mpx.total_flags = new_total_flags;
639 }
640
641 /*
642  * tevent_common_fd_mpx_flags() return the effective flags
643  * (TEVEND_FD_*) of the primary fde and all multiplexed fdes.
644  *
645  * Valid after tevent_common_fd_mpx_update_flags() was called
646  */
647 static inline
648 uint16_t tevent_common_fd_mpx_flags(struct tevent_fd *any_fde)
649 {
650         struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
651
652         return primary->mpx.total_flags;
653 }
654
655 /*
656  * tevent_common_fd_mpx_clear_writeable() clears TEVENT_FD_WRITE
657  * from all fdes belonging together.
658  */
659 static inline
660 void tevent_common_fd_mpx_clear_writeable(struct tevent_fd *any_fde)
661 {
662         struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
663         struct tevent_fd_mpx *mpx = NULL;
664
665         primary->flags &= ~TEVENT_FD_WRITE;
666
667         for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
668                 struct tevent_fd *mpx_fde = mpx->fde;
669                 /* we don't care that mpx_fde might be == primary */
670                 mpx_fde->flags &= ~TEVENT_FD_WRITE;
671         }
672
673         primary->mpx.total_flags &= ~TEVENT_FD_WRITE;
674 }
675
676 /*
677  * tevent_common_fd_mpx_additional_flags() modifies
678  * fde->additional_flags for all fdes belonging together.
679  */
680 static inline
681 void tevent_common_fd_mpx_additional_flags(struct tevent_fd *any_fde,
682                                            uint64_t clear_flags,
683                                            uint64_t add_flags)
684 {
685         struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
686         struct tevent_fd_mpx *mpx = NULL;
687
688         primary->additional_flags &= ~clear_flags;
689         primary->additional_flags |= add_flags;
690
691         for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
692                 struct tevent_fd *mpx_fde = mpx->fde;
693                 /* we don't care that mpx_fde might be == primary */
694                 mpx_fde->additional_flags &= ~clear_flags;
695                 mpx_fde->additional_flags |= add_flags;
696         }
697 }
698
699 /*
700  * tevent_common_fd_mpx_disarm_all() detaches
701  * all fdes currently belonging together from each other
702  * and also from the tevent_context, which means their
703  * handler will never be called again.
704  */
705 static inline
706 void tevent_common_fd_mpx_disarm_all(struct tevent_fd *any_fde)
707 {
708         struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
709         struct tevent_fd_mpx *mpx = NULL, *next = NULL;
710
711         for (mpx = primary->mpx.list; mpx != NULL; mpx = next) {
712                 struct tevent_fd *mpx_fde = mpx->fde;
713
714                 next = mpx->next;
715                 DLIST_REMOVE(primary->mpx.list, mpx);
716
717                 if (mpx_fde == primary) {
718                         /* primary is handled below */
719                         continue;
720                 }
721
722                 tevent_common_fd_disarm(mpx_fde);
723         }
724
725         tevent_common_fd_disarm(primary);
726 }
727
728 /*
729  * tevent_common_fd_mpx_select() selects the handler that
730  * should be called for the given low level event.
731  *
732  * Note it's important to pass the primary fde!
733  */
734 static inline
735 struct tevent_fd *tevent_common_fd_mpx_select(struct tevent_fd *primary,
736                                               uint16_t flags,
737                                               bool got_error)
738 {
739         struct tevent_fd_mpx *mpx = NULL;
740         struct tevent_fd *selected = NULL;
741
742         /* optimize for the single event case. */
743         if (!primary->mpx.has_mpx) {
744                 /*
745                  * If we got an error, we won't report it if
746                  * the caller only asked for TEVENT_FD_WRITE.
747                  */
748                 if (got_error &&
749                     !(primary->flags & (TEVENT_FD_READ|TEVENT_FD_ERROR)))
750                 {
751                         return NULL;
752                 }
753
754                 if (flags & primary->flags) {
755                         return primary;
756                 }
757
758                 return NULL;
759         }
760
761         for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
762                 struct tevent_fd *mpx_fde = mpx->fde;
763
764                 /*
765                  * If we got an error, we won't report it if
766                  * the caller only asked for TEVENT_FD_WRITE.
767                  */
768                 if (got_error &&
769                     !(mpx_fde->flags & (TEVENT_FD_READ|TEVENT_FD_ERROR)))
770                 {
771                         continue;
772                 }
773
774                 if (flags & mpx_fde->flags) {
775                         selected = mpx_fde;
776                         break;
777                 }
778         }
779
780         if (selected == NULL) {
781                 return NULL;
782         }
783
784         /*
785          * Maintain fairness and demote the just selected fde
786          */
787         DLIST_DEMOTE_SHORT(primary->mpx.list, &selected->mpx);
788         return selected;
789 }
790
791 /*
792  * tevent_common_fd_mpx_add() searches for an existing (active) fde
793  * for the same low level fd and adds the given 'add_fde'
794  * as multiplexed to the found fde.
795  *
796  * If another fde was found it is returned.
797  * NULL is returned to indicate no match
798  */
799 static inline
800 struct tevent_fd *tevent_common_fd_mpx_add(struct tevent_fd *add_fde)
801 {
802         struct tevent_context *ev = add_fde->event_ctx;
803         struct tevent_fd *add_primary = tevent_common_fd_mpx_primary(add_fde);
804         uint16_t add_flags = tevent_common_fd_mpx_flags(add_primary);
805         struct tevent_fd *mpx_fde = NULL;
806         struct tevent_fd *mpx_primary = NULL;
807         struct tevent_fd_mpx *tmp = NULL;
808         struct tevent_fd_mpx *next = NULL;
809
810         /* Find the existing fde that caused the EEXIST error. */
811         for (mpx_fde = ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) {
812                 mpx_primary = tevent_common_fd_mpx_primary(mpx_fde);
813
814                 if (mpx_primary->fd != add_primary->fd) {
815                         mpx_primary = NULL;
816                         continue;
817                 }
818
819                 if (mpx_primary == add_primary) {
820                         mpx_primary = NULL;
821                         continue;
822                 }
823
824                 if (add_flags != 0 &&
825                     tevent_common_fd_mpx_flags(mpx_primary) == 0)
826                 {
827                         /*
828                          * only active events should match
829                          */
830                         mpx_primary = NULL;
831                         continue;
832                 }
833                 break;
834         }
835         if (mpx_primary == NULL) {
836                 tevent_debug(ev, TEVENT_DEBUG_FATAL,
837                              "can't find multiplex fde for fd[%d]",
838                              add_fde->fd);
839                 return NULL;
840         }
841
842         /*
843          * If add_primary is not in it's own list
844          * we add it in order to simplify the loop below.
845          */
846
847         if (add_primary->mpx.prev == NULL && add_primary->mpx.next == NULL) {
848                 DLIST_ADD_END(add_primary->mpx.list, &add_primary->mpx);
849         }
850
851         /*
852          * Add the new mpx_primary to its own list before others,
853          * if it is not already added.
854          */
855         if (mpx_primary->mpx.prev == NULL && mpx_primary->mpx.next == NULL) {
856                 DLIST_ADD_END(mpx_primary->mpx.list, &mpx_primary->mpx);
857         }
858
859         /*
860          * Now we clear all entries and move them to the
861          * new primary
862          */
863         for (tmp = add_primary->mpx.list; tmp != NULL; tmp = next) {
864                 struct tevent_fd *tmp_fde = tmp->fde;
865
866                 next = tmp->next;
867
868                 DLIST_REMOVE(add_primary->mpx.list, tmp);
869                 tevent_common_fd_mpx_reinit(tmp_fde);
870                 DLIST_ADD_END(mpx_primary->mpx.list, tmp);
871                 tmp->primary = mpx_primary;
872                 tmp->has_mpx = true;
873         }
874
875         mpx_primary->mpx.has_mpx = true;
876         return mpx_primary;
877 }
878
879 /*
880  * tevent_common_fd_mpx_update() calls tevent_common_fd_mpx_update_flags()
881  * and compares tevent_common_fd_mpx_flags() before and after.
882  *
883  * When there's a low level update needed the primary fde,
884  * otherwise NULL is returned.
885  */
886 static inline
887 struct tevent_fd *tevent_common_fd_mpx_update(struct tevent_fd *update_fde)
888 {
889         struct tevent_fd *primary = tevent_common_fd_mpx_primary(update_fde);
890         uint16_t old_total_flags;
891         uint16_t new_total_flags;
892
893         old_total_flags = primary->mpx.total_flags;
894         tevent_common_fd_mpx_update_flags(primary);
895         new_total_flags = primary->mpx.total_flags;
896
897         if (old_total_flags == new_total_flags) {
898                 /* No update needed */
899                 return NULL;
900         }
901
902         return primary;
903 }
904
905 /*
906  * tevent_common_fd_mpx_remove() removes remove_fde from its possible primary,
907  * if remove_fde is a primary itself, a new primary is selected.
908  *
909  * The remaining primary or NULL is returned.
910  */
911 static inline
912 struct tevent_fd *tevent_common_fd_mpx_remove(struct tevent_fd *remove_fde)
913 {
914         struct tevent_fd *primary = tevent_common_fd_mpx_primary(remove_fde);
915         struct tevent_fd_mpx *mpx = NULL, *next = NULL;
916         struct tevent_fd *new_primary = NULL;
917
918         DLIST_REMOVE(primary->mpx.list, &remove_fde->mpx);
919
920         if (primary != remove_fde) {
921                 tevent_common_fd_mpx_reinit(remove_fde);
922                 return primary;
923         }
924
925         for (mpx = primary->mpx.list; mpx != NULL; mpx = next) {
926                 struct tevent_fd *mpx_fde = mpx->fde;
927
928                 next = mpx->next;
929
930                 DLIST_REMOVE(primary->mpx.list, &mpx_fde->mpx);
931                 tevent_common_fd_mpx_reinit(mpx_fde);
932                 mpx->primary = new_primary;
933                 if (new_primary == NULL) {
934                         /*
935                          * Select the first one as the new primary and add
936                          * itself as the first mpx-fde to the mpx list
937                          */
938                         new_primary = mpx_fde;
939                         DLIST_ADD(new_primary->mpx.list, &mpx_fde->mpx);
940                         continue;
941                 }
942                 new_primary->mpx.has_mpx = true;
943                 mpx->has_mpx = true;
944                 DLIST_ADD_END(new_primary->mpx.list, &mpx_fde->mpx);
945         }
946
947         /* primary == remove_fde */
948         tevent_common_fd_mpx_reinit(primary);
949         return new_primary;
950 }