Coverage Report

Created: 2026-02-14 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/lib/tevent/tevent_internal.h
Line
Count
Source
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
0
#define TEVENT_DEBUG(__ev, __level, __fmt, ...) do { \
308
0
  if (unlikely((__ev) != NULL && \
309
0
         (__level) <= (__ev)->debug_ops.max_level)) \
310
0
  { \
311
0
    tevent_debug((__ev), (__level), (__fmt), __VA_ARGS__); \
312
0
  } \
313
0
} 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
  struct timeval wait_timeout;
421
422
#ifdef HAVE_PTHREAD
423
  struct tevent_context *prev, *next;
424
#endif
425
};
426
427
int tevent_common_context_destructor(struct tevent_context *ev);
428
int tevent_common_loop_wait(struct tevent_context *ev,
429
          const char *location);
430
431
struct tevent_common_fd_buf {
432
  char buf[128];
433
};
434
435
const char *tevent_common_fd_str(struct tevent_common_fd_buf *buf,
436
         const char *description,
437
         const struct tevent_fd *fde);
438
439
int tevent_common_fd_destructor(struct tevent_fd *fde);
440
struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev,
441
               TALLOC_CTX *mem_ctx,
442
               int fd,
443
               uint16_t flags,
444
               tevent_fd_handler_t handler,
445
               void *private_data,
446
               const char *handler_name,
447
               const char *location);
448
void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
449
           tevent_fd_close_fn_t close_fn);
450
uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
451
void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
452
int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
453
            bool *removed);
454
455
struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
456
               TALLOC_CTX *mem_ctx,
457
               struct timeval next_event,
458
               tevent_timer_handler_t handler,
459
               void *private_data,
460
               const char *handler_name,
461
               const char *location);
462
struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev,
463
            TALLOC_CTX *mem_ctx,
464
                  struct timeval next_event,
465
                  tevent_timer_handler_t handler,
466
                  void *private_data,
467
                  const char *handler_name,
468
                  const char *location);
469
struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
470
471
/* timeout values for poll(2) / epoll_wait(2) */
472
static inline bool tevent_common_no_timeout(const struct timeval *tv)
473
0
{
474
0
  if ((tv->tv_sec == 0) && (tv->tv_usec == INT32_MAX)) {
475
    /*
476
     * This is special from
477
     * tevent_context_set_wait_timeout(0)
478
     */
479
0
    return true;
480
0
  }
481
0
  return false;
482
0
}
Unexecuted instantiation: tevent.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_debug.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_fd.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_immediate.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_queue.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_req.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_wrapper.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_poll.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_threads.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_signal.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_standard.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_timed.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_util.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_wakeup.c:tevent_common_no_timeout
Unexecuted instantiation: tevent_epoll.c:tevent_common_no_timeout
483
static inline int tevent_common_timeout_msec(const struct timeval *tv)
484
0
{
485
0
  if (tv->tv_sec == INT32_MAX) {
486
0
    return -1;
487
0
  }
488
0
  if (tevent_common_no_timeout(tv)) {
489
    /*
490
     * This is special from
491
     * tevent_context_set_wait_timeout(0)
492
     */
493
0
    return 0;
494
0
  }
495
0
  return ((tv->tv_usec + 999) / 1000) + (tv->tv_sec * 1000);
496
0
}
Unexecuted instantiation: tevent.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_debug.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_fd.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_immediate.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_queue.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_req.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_wrapper.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_poll.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_threads.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_signal.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_standard.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_timed.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_util.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_wakeup.c:tevent_common_timeout_msec
Unexecuted instantiation: tevent_epoll.c:tevent_common_timeout_msec
497
498
int tevent_common_invoke_timer_handler(struct tevent_timer *te,
499
               struct timeval current_time,
500
               bool *removed);
501
502
void tevent_common_immediate_cancel(struct tevent_immediate *im);
503
void tevent_common_schedule_immediate(struct tevent_immediate *im,
504
              struct tevent_context *ev,
505
              tevent_immediate_handler_t handler,
506
              void *private_data,
507
              const char *handler_name,
508
              const char *location);
509
int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
510
             bool *removed);
511
bool tevent_common_loop_immediate(struct tevent_context *ev);
512
void tevent_common_threaded_activate_immediate(struct tevent_context *ev);
513
514
bool tevent_common_have_events(struct tevent_context *ev);
515
int tevent_common_wakeup_init(struct tevent_context *ev);
516
int tevent_common_wakeup_fd(int fd);
517
int tevent_common_wakeup(struct tevent_context *ev);
518
519
struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
520
                 TALLOC_CTX *mem_ctx,
521
                 int signum,
522
                 int sa_flags,
523
                 tevent_signal_handler_t handler,
524
                 void *private_data,
525
                 const char *handler_name,
526
                 const char *location);
527
int tevent_common_check_signal(struct tevent_context *ev);
528
void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se);
529
int tevent_common_invoke_signal_handler(struct tevent_signal *se,
530
          int signum, int count, void *siginfo,
531
          bool *removed);
532
533
struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev);
534
535
struct tevent_wrapper_ops;
536
537
struct tevent_wrapper_glue {
538
  struct tevent_wrapper_glue *prev, *next;
539
  struct tevent_context *wrap_ev;
540
  struct tevent_context *main_ev;
541
  bool busy;
542
  bool destroyed;
543
  const struct tevent_wrapper_ops *ops;
544
  void *private_state;
545
};
546
547
void tevent_wrapper_push_use_internal(struct tevent_context *ev,
548
              struct tevent_wrapper_glue *wrapper);
549
void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr,
550
             struct tevent_wrapper_glue *wrapper);
551
552
bool tevent_standard_init(void);
553
bool tevent_poll_init(void);
554
bool tevent_poll_event_add_fd_internal(struct tevent_context *ev,
555
               struct tevent_fd *fde);
556
bool tevent_poll_mt_init(void);
557
#ifdef HAVE_EPOLL
558
bool tevent_epoll_init(void);
559
void tevent_epoll_set_panic_fallback(struct tevent_context *ev,
560
      bool (*panic_fallback)(struct tevent_context *ev,
561
                 bool replay));
562
#endif
563
564
static inline void tevent_thread_call_depth_notify(
565
      enum tevent_thread_call_depth_cmd cmd,
566
      struct tevent_req *req,
567
      size_t depth,
568
      const char *fname)
569
0
{
570
0
  if (tevent_thread_call_depth_state_g.cb != NULL) {
571
0
    tevent_thread_call_depth_state_g.cb(
572
0
      tevent_thread_call_depth_state_g.cb_private,
573
0
      cmd,
574
0
      req,
575
0
      depth,
576
0
      fname);
577
0
  }
578
0
}
Unexecuted instantiation: tevent.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_debug.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_fd.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_immediate.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_queue.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_req.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_wrapper.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_poll.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_threads.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_signal.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_standard.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_timed.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_util.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_wakeup.c:tevent_thread_call_depth_notify
Unexecuted instantiation: tevent_epoll.c:tevent_thread_call_depth_notify
579
580
void tevent_trace_point_callback(struct tevent_context *ev,
581
         enum tevent_trace_point);
582
583
void tevent_trace_fd_callback(struct tevent_context *ev,
584
            struct tevent_fd *fde,
585
            enum tevent_event_trace_point);
586
587
void tevent_trace_signal_callback(struct tevent_context *ev,
588
          struct tevent_signal *se,
589
          enum tevent_event_trace_point);
590
591
void tevent_trace_timer_callback(struct tevent_context *ev,
592
         struct tevent_timer *te,
593
         enum tevent_event_trace_point);
594
595
void tevent_trace_immediate_callback(struct tevent_context *ev,
596
             struct tevent_immediate *im,
597
             enum tevent_event_trace_point);
598
599
void tevent_trace_queue_callback(struct tevent_context *ev,
600
         struct tevent_queue_entry *qe,
601
         enum tevent_event_trace_point);
602
603
#include "tevent_dlinklist.h"
604
605
static inline void tevent_common_fd_mpx_reinit(struct tevent_fd *fde)
606
0
{
607
0
  fde->mpx = (struct tevent_fd_mpx) { .fde = fde, };
608
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_reinit
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_reinit
609
610
static inline void tevent_common_fd_disarm(struct tevent_fd *fde)
611
0
{
612
0
  if (fde->event_ctx != NULL) {
613
0
    tevent_trace_fd_callback(fde->event_ctx, fde,
614
0
           TEVENT_EVENT_TRACE_DETACH);
615
0
    DLIST_REMOVE(fde->event_ctx->fd_events, fde);
616
0
    fde->event_ctx = NULL;
617
0
  }
618
0
  tevent_common_fd_mpx_reinit(fde);
619
0
  fde->wrapper = NULL;
620
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_req.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_util.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_disarm
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_disarm
621
622
/*
623
 * tevent_common_fd_mpx_primary() returns the fde that is responsible
624
 * for the low level state.
625
 *
626
 * By default (when there's no multiplexing) it just returns 'any_fde'.
627
 *
628
 * Note it always returns a valid pointer.
629
 */
630
static inline
631
struct tevent_fd *tevent_common_fd_mpx_primary(struct tevent_fd *any_fde)
632
0
{
633
0
  struct tevent_fd *primary = NULL;
634
635
0
  if (any_fde->mpx.primary != NULL) {
636
0
    primary = any_fde->mpx.primary;
637
0
  } else {
638
0
    primary = any_fde;
639
0
  }
640
641
0
  return primary;
642
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_primary
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_primary
643
644
/*
645
 * tevent_common_fd_mpx_update_flags() needs to be called
646
 * if update_fde->flags has changed. It is needed in
647
 * order to let tevent_common_fd_mpx_flags() return a valid
648
 * result.
649
 */
650
static inline
651
void tevent_common_fd_mpx_update_flags(struct tevent_fd *update_fde)
652
0
{
653
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(update_fde);
654
0
  struct tevent_fd_mpx *mpx = NULL;
655
0
  uint16_t new_total_flags = 0;
656
657
0
  if (!primary->mpx.has_mpx) {
658
0
    primary->mpx.total_flags = primary->flags;
659
0
    return;
660
0
  }
661
662
0
  for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
663
0
    struct tevent_fd *mpx_fde = mpx->fde;
664
    /* we don't care that mpx_fde might be == primary */
665
0
    new_total_flags |= mpx_fde->flags;
666
0
  }
667
668
0
  primary->mpx.total_flags = new_total_flags;
669
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_update_flags
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_update_flags
670
671
/*
672
 * tevent_common_fd_mpx_flags() return the effective flags
673
 * (TEVEND_FD_*) of the primary fde and all multiplexed fdes.
674
 *
675
 * Valid after tevent_common_fd_mpx_update_flags() was called
676
 */
677
static inline
678
uint16_t tevent_common_fd_mpx_flags(struct tevent_fd *any_fde)
679
0
{
680
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
681
682
0
  return primary->mpx.total_flags;
683
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_flags
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_flags
684
685
/*
686
 * tevent_common_fd_mpx_clear_writeable() clears TEVENT_FD_WRITE
687
 * from all fdes belonging together.
688
 */
689
static inline
690
void tevent_common_fd_mpx_clear_writeable(struct tevent_fd *any_fde)
691
0
{
692
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
693
0
  struct tevent_fd_mpx *mpx = NULL;
694
695
0
  primary->flags &= ~TEVENT_FD_WRITE;
696
697
0
  for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
698
0
    struct tevent_fd *mpx_fde = mpx->fde;
699
    /* we don't care that mpx_fde might be == primary */
700
0
    mpx_fde->flags &= ~TEVENT_FD_WRITE;
701
0
  }
702
703
0
  primary->mpx.total_flags &= ~TEVENT_FD_WRITE;
704
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_clear_writeable
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_clear_writeable
705
706
/*
707
 * tevent_common_fd_mpx_additional_flags() modifies
708
 * fde->additional_flags for all fdes belonging together.
709
 */
710
static inline
711
void tevent_common_fd_mpx_additional_flags(struct tevent_fd *any_fde,
712
             uint64_t clear_flags,
713
             uint64_t add_flags)
714
0
{
715
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
716
0
  struct tevent_fd_mpx *mpx = NULL;
717
718
0
  primary->additional_flags &= ~clear_flags;
719
0
  primary->additional_flags |= add_flags;
720
721
0
  for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
722
0
    struct tevent_fd *mpx_fde = mpx->fde;
723
    /* we don't care that mpx_fde might be == primary */
724
0
    mpx_fde->additional_flags &= ~clear_flags;
725
0
    mpx_fde->additional_flags |= add_flags;
726
0
  }
727
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_additional_flags
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_additional_flags
728
729
/*
730
 * tevent_common_fd_mpx_disarm_all() detaches
731
 * all fdes currently belonging together from each other
732
 * and also from the tevent_context, which means their
733
 * handler will never be called again.
734
 */
735
static inline
736
void tevent_common_fd_mpx_disarm_all(struct tevent_fd *any_fde)
737
0
{
738
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(any_fde);
739
0
  struct tevent_fd_mpx *mpx = NULL, *next = NULL;
740
741
0
  for (mpx = primary->mpx.list; mpx != NULL; mpx = next) {
742
0
    struct tevent_fd *mpx_fde = mpx->fde;
743
744
0
    next = mpx->next;
745
0
    DLIST_REMOVE(primary->mpx.list, mpx);
746
747
0
    if (mpx_fde == primary) {
748
      /* primary is handled below */
749
0
      continue;
750
0
    }
751
752
0
    tevent_common_fd_disarm(mpx_fde);
753
0
  }
754
755
0
  tevent_common_fd_disarm(primary);
756
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_disarm_all
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_disarm_all
757
758
/*
759
 * tevent_common_fd_mpx_select() selects the handler that
760
 * should be called for the given low level event.
761
 *
762
 * Note it's important to pass the primary fde!
763
 */
764
static inline
765
struct tevent_fd *tevent_common_fd_mpx_select(struct tevent_fd *primary,
766
                uint16_t flags,
767
                bool got_error)
768
0
{
769
0
  struct tevent_fd_mpx *mpx = NULL;
770
0
  struct tevent_fd *selected = NULL;
771
772
  /* optimize for the single event case. */
773
0
  if (!primary->mpx.has_mpx) {
774
    /*
775
     * If we got an error, we won't report it if
776
     * the caller only asked for TEVENT_FD_WRITE.
777
     */
778
0
    if (got_error &&
779
0
        !(primary->flags & (TEVENT_FD_READ|TEVENT_FD_ERROR)))
780
0
    {
781
0
      return NULL;
782
0
    }
783
784
0
    if (flags & primary->flags) {
785
0
      return primary;
786
0
    }
787
788
0
    return NULL;
789
0
  }
790
791
0
  for (mpx = primary->mpx.list; mpx != NULL; mpx = mpx->next) {
792
0
    struct tevent_fd *mpx_fde = mpx->fde;
793
794
    /*
795
     * If we got an error, we won't report it if
796
     * the caller only asked for TEVENT_FD_WRITE.
797
     */
798
0
    if (got_error &&
799
0
        !(mpx_fde->flags & (TEVENT_FD_READ|TEVENT_FD_ERROR)))
800
0
    {
801
0
      continue;
802
0
    }
803
804
0
    if (flags & mpx_fde->flags) {
805
0
      selected = mpx_fde;
806
0
      break;
807
0
    }
808
0
  }
809
810
0
  if (selected == NULL) {
811
0
    return NULL;
812
0
  }
813
814
  /*
815
   * Maintain fairness and demote the just selected fde
816
   */
817
0
  DLIST_DEMOTE_SHORT(primary->mpx.list, &selected->mpx);
818
0
  return selected;
819
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_select
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_select
820
821
/*
822
 * tevent_common_fd_mpx_add() searches for an existing (active) fde
823
 * for the same low level fd and adds the given 'add_fde'
824
 * as multiplexed to the found fde.
825
 *
826
 * If another fde was found it is returned.
827
 * NULL is returned to indicate no match
828
 */
829
static inline
830
struct tevent_fd *tevent_common_fd_mpx_add(struct tevent_fd *add_fde)
831
0
{
832
0
  struct tevent_context *ev = add_fde->event_ctx;
833
0
  struct tevent_fd *add_primary = tevent_common_fd_mpx_primary(add_fde);
834
0
  uint16_t add_flags = tevent_common_fd_mpx_flags(add_primary);
835
0
  struct tevent_fd *mpx_fde = NULL;
836
0
  struct tevent_fd *mpx_primary = NULL;
837
0
  struct tevent_fd_mpx *tmp = NULL;
838
0
  struct tevent_fd_mpx *next = NULL;
839
840
  /* Find the existing fde that caused the EEXIST error. */
841
0
  for (mpx_fde = ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) {
842
0
    mpx_primary = tevent_common_fd_mpx_primary(mpx_fde);
843
844
0
    if (mpx_primary->fd != add_primary->fd) {
845
0
      mpx_primary = NULL;
846
0
      continue;
847
0
    }
848
849
0
    if (mpx_primary == add_primary) {
850
0
      mpx_primary = NULL;
851
0
      continue;
852
0
    }
853
854
0
    if (add_flags != 0 &&
855
0
        tevent_common_fd_mpx_flags(mpx_primary) == 0)
856
0
    {
857
      /*
858
       * only active events should match
859
       */
860
0
      mpx_primary = NULL;
861
0
      continue;
862
0
    }
863
0
    break;
864
0
  }
865
0
  if (mpx_primary == NULL) {
866
0
    tevent_debug(ev, TEVENT_DEBUG_FATAL,
867
0
           "can't find multiplex fde for fd[%d]",
868
0
           add_fde->fd);
869
0
    return NULL;
870
0
  }
871
872
  /*
873
   * If add_primary is not in it's own list
874
   * we add it in order to simplify the loop below.
875
   */
876
877
0
  if (add_primary->mpx.prev == NULL && add_primary->mpx.next == NULL) {
878
0
    DLIST_ADD_END(add_primary->mpx.list, &add_primary->mpx);
879
0
  }
880
881
  /*
882
   * Add the new mpx_primary to its own list before others,
883
   * if it is not already added.
884
   */
885
0
  if (mpx_primary->mpx.prev == NULL && mpx_primary->mpx.next == NULL) {
886
0
    DLIST_ADD_END(mpx_primary->mpx.list, &mpx_primary->mpx);
887
0
  }
888
889
  /*
890
   * Now we clear all entries and move them to the
891
   * new primary
892
   */
893
0
  for (tmp = add_primary->mpx.list; tmp != NULL; tmp = next) {
894
0
    struct tevent_fd *tmp_fde = tmp->fde;
895
896
0
    next = tmp->next;
897
898
0
    DLIST_REMOVE(add_primary->mpx.list, tmp);
899
0
    tevent_common_fd_mpx_reinit(tmp_fde);
900
0
    DLIST_ADD_END(mpx_primary->mpx.list, tmp);
901
0
    tmp->primary = mpx_primary;
902
0
    tmp->has_mpx = true;
903
0
  }
904
905
0
  mpx_primary->mpx.has_mpx = true;
906
0
  return mpx_primary;
907
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_add
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_add
908
909
/*
910
 * tevent_common_fd_mpx_update() calls tevent_common_fd_mpx_update_flags()
911
 * and compares tevent_common_fd_mpx_flags() before and after.
912
 *
913
 * When there's a low level update needed the primary fde,
914
 * otherwise NULL is returned.
915
 */
916
static inline
917
struct tevent_fd *tevent_common_fd_mpx_update(struct tevent_fd *update_fde)
918
0
{
919
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(update_fde);
920
0
  uint16_t old_total_flags;
921
0
  uint16_t new_total_flags;
922
923
0
  old_total_flags = primary->mpx.total_flags;
924
0
  tevent_common_fd_mpx_update_flags(primary);
925
0
  new_total_flags = primary->mpx.total_flags;
926
927
0
  if (old_total_flags == new_total_flags) {
928
    /* No update needed */
929
0
    return NULL;
930
0
  }
931
932
0
  return primary;
933
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_update
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_update
934
935
/*
936
 * tevent_common_fd_mpx_remove() removes remove_fde from its possible primary,
937
 * if remove_fde is a primary itself, a new primary is selected.
938
 *
939
 * The remaining primary or NULL is returned.
940
 */
941
static inline
942
struct tevent_fd *tevent_common_fd_mpx_remove(struct tevent_fd *remove_fde)
943
0
{
944
0
  struct tevent_fd *primary = tevent_common_fd_mpx_primary(remove_fde);
945
0
  struct tevent_fd_mpx *mpx = NULL, *next = NULL;
946
0
  struct tevent_fd *new_primary = NULL;
947
948
0
  DLIST_REMOVE(primary->mpx.list, &remove_fde->mpx);
949
950
0
  if (primary != remove_fde) {
951
0
    tevent_common_fd_mpx_reinit(remove_fde);
952
0
    return primary;
953
0
  }
954
955
0
  for (mpx = primary->mpx.list; mpx != NULL; mpx = next) {
956
0
    struct tevent_fd *mpx_fde = mpx->fde;
957
958
0
    next = mpx->next;
959
960
0
    DLIST_REMOVE(primary->mpx.list, &mpx_fde->mpx);
961
0
    tevent_common_fd_mpx_reinit(mpx_fde);
962
0
    mpx->primary = new_primary;
963
0
    if (new_primary == NULL) {
964
      /*
965
       * Select the first one as the new primary and add
966
       * itself as the first mpx-fde to the mpx list
967
       */
968
0
      new_primary = mpx_fde;
969
0
      DLIST_ADD(new_primary->mpx.list, &mpx_fde->mpx);
970
0
      continue;
971
0
    }
972
0
    new_primary->mpx.has_mpx = true;
973
0
    mpx->has_mpx = true;
974
0
    DLIST_ADD_END(new_primary->mpx.list, &mpx_fde->mpx);
975
0
  }
976
977
  /* primary == remove_fde */
978
0
  tevent_common_fd_mpx_reinit(primary);
979
0
  return new_primary;
980
0
}
Unexecuted instantiation: tevent.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_debug.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_fd.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_immediate.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_queue.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_req.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_wrapper.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_poll.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_threads.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_signal.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_standard.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_timed.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_util.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_wakeup.c:tevent_common_fd_mpx_remove
Unexecuted instantiation: tevent_epoll.c:tevent_common_fd_mpx_remove