~binli/ubuntu/vivid/pulseaudio/fix-atoi

« back to all changes in this revision

Viewing changes to src/pulse/mainloop.c

  • Committer: Bin Li
  • Date: 2016-07-05 03:39:49 UTC
  • Revision ID: bin.li@canonical.com-20160705033949-rz4p9x4hbi2danxk
first version based on pulseaudio_6.0-0ubuntu9.27

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***
 
2
  This file is part of PulseAudio.
 
3
 
 
4
  Copyright 2004-2006 Lennart Poettering
 
5
  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
 
6
 
 
7
  PulseAudio is free software; you can redistribute it and/or modify
 
8
  it under the terms of the GNU Lesser General Public License as published
 
9
  by the Free Software Foundation; either version 2.1 of the License,
 
10
  or (at your option) any later version.
 
11
 
 
12
  PulseAudio is distributed in the hope that it will be useful, but
 
13
  WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
15
  General Public License for more details.
 
16
 
 
17
  You should have received a copy of the GNU Lesser General Public License
 
18
  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 
19
***/
 
20
 
 
21
#ifdef HAVE_CONFIG_H
 
22
#include <config.h>
 
23
#endif
 
24
 
 
25
#include <stdio.h>
 
26
#include <unistd.h>
 
27
#include <stdlib.h>
 
28
#include <fcntl.h>
 
29
#include <errno.h>
 
30
 
 
31
#ifndef HAVE_PIPE
 
32
#include <pulsecore/pipe.h>
 
33
#endif
 
34
 
 
35
#include <pulse/rtclock.h>
 
36
#include <pulse/timeval.h>
 
37
#include <pulse/xmalloc.h>
 
38
 
 
39
#include <pulsecore/poll.h>
 
40
#include <pulsecore/core-rtclock.h>
 
41
#include <pulsecore/core-util.h>
 
42
#include <pulsecore/i18n.h>
 
43
#include <pulsecore/llist.h>
 
44
#include <pulsecore/log.h>
 
45
#include <pulsecore/core-error.h>
 
46
#include <pulsecore/socket.h>
 
47
#include <pulsecore/macro.h>
 
48
 
 
49
#include "mainloop.h"
 
50
#include "internal.h"
 
51
 
 
52
struct pa_io_event {
 
53
    pa_mainloop *mainloop;
 
54
    bool dead:1;
 
55
 
 
56
    int fd;
 
57
    pa_io_event_flags_t events;
 
58
    struct pollfd *pollfd;
 
59
 
 
60
    pa_io_event_cb_t callback;
 
61
    void *userdata;
 
62
    pa_io_event_destroy_cb_t destroy_callback;
 
63
 
 
64
    PA_LLIST_FIELDS(pa_io_event);
 
65
};
 
66
 
 
67
struct pa_time_event {
 
68
    pa_mainloop *mainloop;
 
69
    bool dead:1;
 
70
 
 
71
    bool enabled:1;
 
72
    bool use_rtclock:1;
 
73
    pa_usec_t time;
 
74
 
 
75
    pa_time_event_cb_t callback;
 
76
    void *userdata;
 
77
    pa_time_event_destroy_cb_t destroy_callback;
 
78
 
 
79
    PA_LLIST_FIELDS(pa_time_event);
 
80
};
 
81
 
 
82
struct pa_defer_event {
 
83
    pa_mainloop *mainloop;
 
84
    bool dead:1;
 
85
 
 
86
    bool enabled:1;
 
87
 
 
88
    pa_defer_event_cb_t callback;
 
89
    void *userdata;
 
90
    pa_defer_event_destroy_cb_t destroy_callback;
 
91
 
 
92
    PA_LLIST_FIELDS(pa_defer_event);
 
93
};
 
94
 
 
95
struct pa_mainloop {
 
96
    PA_LLIST_HEAD(pa_io_event, io_events);
 
97
    PA_LLIST_HEAD(pa_time_event, time_events);
 
98
    PA_LLIST_HEAD(pa_defer_event, defer_events);
 
99
 
 
100
    unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
 
101
    unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
 
102
 
 
103
    bool rebuild_pollfds:1;
 
104
    struct pollfd *pollfds;
 
105
    unsigned max_pollfds, n_pollfds;
 
106
 
 
107
    pa_usec_t prepared_timeout;
 
108
    pa_time_event *cached_next_time_event;
 
109
 
 
110
    pa_mainloop_api api;
 
111
 
 
112
    int retval;
 
113
    bool quit:1;
 
114
 
 
115
    int wakeup_pipe[2];
 
116
    int wakeup_pipe_type;
 
117
 
 
118
    enum {
 
119
        STATE_PASSIVE,
 
120
        STATE_PREPARED,
 
121
        STATE_POLLING,
 
122
        STATE_POLLED,
 
123
        STATE_QUIT
 
124
    } state;
 
125
 
 
126
    pa_poll_func poll_func;
 
127
    void *poll_func_userdata;
 
128
    int poll_func_ret;
 
129
};
 
130
 
 
131
static short map_flags_to_libc(pa_io_event_flags_t flags) {
 
132
    return (short)
 
133
        ((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
 
134
         (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
 
135
         (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
 
136
         (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0));
 
137
}
 
138
 
 
139
static pa_io_event_flags_t map_flags_from_libc(short flags) {
 
140
    return
 
141
        (flags & POLLIN ? PA_IO_EVENT_INPUT : 0) |
 
142
        (flags & POLLOUT ? PA_IO_EVENT_OUTPUT : 0) |
 
143
        (flags & POLLERR ? PA_IO_EVENT_ERROR : 0) |
 
144
        (flags & POLLHUP ? PA_IO_EVENT_HANGUP : 0);
 
145
}
 
146
 
 
147
/* IO events */
 
148
static pa_io_event* mainloop_io_new(
 
149
        pa_mainloop_api *a,
 
150
        int fd,
 
151
        pa_io_event_flags_t events,
 
152
        pa_io_event_cb_t callback,
 
153
        void *userdata) {
 
154
 
 
155
    pa_mainloop *m;
 
156
    pa_io_event *e;
 
157
 
 
158
    pa_assert(a);
 
159
    pa_assert(a->userdata);
 
160
    pa_assert(fd >= 0);
 
161
    pa_assert(callback);
 
162
 
 
163
    m = a->userdata;
 
164
    pa_assert(a == &m->api);
 
165
 
 
166
    e = pa_xnew0(pa_io_event, 1);
 
167
    e->mainloop = m;
 
168
 
 
169
    e->fd = fd;
 
170
    e->events = events;
 
171
 
 
172
    e->callback = callback;
 
173
    e->userdata = userdata;
 
174
 
 
175
    PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
 
176
    m->rebuild_pollfds = true;
 
177
    m->n_io_events ++;
 
178
 
 
179
    pa_mainloop_wakeup(m);
 
180
 
 
181
    return e;
 
182
}
 
183
 
 
184
static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
 
185
    pa_assert(e);
 
186
    pa_assert(!e->dead);
 
187
 
 
188
    if (e->events == events)
 
189
        return;
 
190
 
 
191
    e->events = events;
 
192
 
 
193
    if (e->pollfd)
 
194
        e->pollfd->events = map_flags_to_libc(events);
 
195
    else
 
196
        e->mainloop->rebuild_pollfds = true;
 
197
 
 
198
    pa_mainloop_wakeup(e->mainloop);
 
199
}
 
200
 
 
201
static void mainloop_io_free(pa_io_event *e) {
 
202
    pa_assert(e);
 
203
    pa_assert(!e->dead);
 
204
 
 
205
    e->dead = true;
 
206
    e->mainloop->io_events_please_scan ++;
 
207
 
 
208
    e->mainloop->n_io_events --;
 
209
    e->mainloop->rebuild_pollfds = true;
 
210
 
 
211
    pa_mainloop_wakeup(e->mainloop);
 
212
}
 
213
 
 
214
static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
 
215
    pa_assert(e);
 
216
 
 
217
    e->destroy_callback = callback;
 
218
}
 
219
 
 
220
/* Defer events */
 
221
static pa_defer_event* mainloop_defer_new(
 
222
        pa_mainloop_api *a,
 
223
        pa_defer_event_cb_t callback,
 
224
        void *userdata) {
 
225
 
 
226
    pa_mainloop *m;
 
227
    pa_defer_event *e;
 
228
 
 
229
    pa_assert(a);
 
230
    pa_assert(a->userdata);
 
231
    pa_assert(callback);
 
232
 
 
233
    m = a->userdata;
 
234
    pa_assert(a == &m->api);
 
235
 
 
236
    e = pa_xnew0(pa_defer_event, 1);
 
237
    e->mainloop = m;
 
238
 
 
239
    e->enabled = true;
 
240
    m->n_enabled_defer_events++;
 
241
 
 
242
    e->callback = callback;
 
243
    e->userdata = userdata;
 
244
 
 
245
    PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
 
246
 
 
247
    pa_mainloop_wakeup(e->mainloop);
 
248
 
 
249
    return e;
 
250
}
 
251
 
 
252
static void mainloop_defer_enable(pa_defer_event *e, int b) {
 
253
    pa_assert(e);
 
254
    pa_assert(!e->dead);
 
255
 
 
256
    if (e->enabled && !b) {
 
257
        pa_assert(e->mainloop->n_enabled_defer_events > 0);
 
258
        e->mainloop->n_enabled_defer_events--;
 
259
    } else if (!e->enabled && b) {
 
260
        e->mainloop->n_enabled_defer_events++;
 
261
        pa_mainloop_wakeup(e->mainloop);
 
262
    }
 
263
 
 
264
    e->enabled = b;
 
265
}
 
266
 
 
267
static void mainloop_defer_free(pa_defer_event *e) {
 
268
    pa_assert(e);
 
269
    pa_assert(!e->dead);
 
270
 
 
271
    e->dead = true;
 
272
    e->mainloop->defer_events_please_scan ++;
 
273
 
 
274
    if (e->enabled) {
 
275
        pa_assert(e->mainloop->n_enabled_defer_events > 0);
 
276
        e->mainloop->n_enabled_defer_events--;
 
277
        e->enabled = false;
 
278
    }
 
279
}
 
280
 
 
281
static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) {
 
282
    pa_assert(e);
 
283
    pa_assert(!e->dead);
 
284
 
 
285
    e->destroy_callback = callback;
 
286
}
 
287
 
 
288
/* Time events */
 
289
static pa_usec_t make_rt(const struct timeval *tv, bool *use_rtclock) {
 
290
    struct timeval ttv;
 
291
 
 
292
    if (!tv) {
 
293
        *use_rtclock = false;
 
294
        return PA_USEC_INVALID;
 
295
    }
 
296
 
 
297
    ttv = *tv;
 
298
    *use_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK);
 
299
 
 
300
    if (*use_rtclock)
 
301
        ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK;
 
302
    else
 
303
        pa_rtclock_from_wallclock(&ttv);
 
304
 
 
305
    return pa_timeval_load(&ttv);
 
306
}
 
307
 
 
308
static pa_time_event* mainloop_time_new(
 
309
        pa_mainloop_api *a,
 
310
        const struct timeval *tv,
 
311
        pa_time_event_cb_t callback,
 
312
        void *userdata) {
 
313
 
 
314
    pa_mainloop *m;
 
315
    pa_time_event *e;
 
316
    pa_usec_t t;
 
317
    bool use_rtclock = false;
 
318
 
 
319
    pa_assert(a);
 
320
    pa_assert(a->userdata);
 
321
    pa_assert(callback);
 
322
 
 
323
    t = make_rt(tv, &use_rtclock);
 
324
 
 
325
    m = a->userdata;
 
326
    pa_assert(a == &m->api);
 
327
 
 
328
    e = pa_xnew0(pa_time_event, 1);
 
329
    e->mainloop = m;
 
330
 
 
331
    if ((e->enabled = (t != PA_USEC_INVALID))) {
 
332
        e->time = t;
 
333
        e->use_rtclock = use_rtclock;
 
334
 
 
335
        m->n_enabled_time_events++;
 
336
 
 
337
        if (m->cached_next_time_event) {
 
338
            pa_assert(m->cached_next_time_event->enabled);
 
339
 
 
340
            if (t < m->cached_next_time_event->time)
 
341
                m->cached_next_time_event = e;
 
342
        }
 
343
    }
 
344
 
 
345
    e->callback = callback;
 
346
    e->userdata = userdata;
 
347
 
 
348
    PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
 
349
 
 
350
    if (e->enabled)
 
351
        pa_mainloop_wakeup(m);
 
352
 
 
353
    return e;
 
354
}
 
355
 
 
356
static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
 
357
    bool valid;
 
358
    pa_usec_t t;
 
359
    bool use_rtclock = false;
 
360
 
 
361
    pa_assert(e);
 
362
    pa_assert(!e->dead);
 
363
 
 
364
    t = make_rt(tv, &use_rtclock);
 
365
 
 
366
    valid = (t != PA_USEC_INVALID);
 
367
    if (e->enabled && !valid) {
 
368
        pa_assert(e->mainloop->n_enabled_time_events > 0);
 
369
        e->mainloop->n_enabled_time_events--;
 
370
    } else if (!e->enabled && valid)
 
371
        e->mainloop->n_enabled_time_events++;
 
372
 
 
373
    if ((e->enabled = valid)) {
 
374
        e->time = t;
 
375
        e->use_rtclock = use_rtclock;
 
376
        pa_mainloop_wakeup(e->mainloop);
 
377
    }
 
378
 
 
379
    if (e->mainloop->cached_next_time_event == e)
 
380
        e->mainloop->cached_next_time_event = NULL;
 
381
 
 
382
    if (e->mainloop->cached_next_time_event && e->enabled) {
 
383
        pa_assert(e->mainloop->cached_next_time_event->enabled);
 
384
 
 
385
        if (t < e->mainloop->cached_next_time_event->time)
 
386
            e->mainloop->cached_next_time_event = e;
 
387
    }
 
388
}
 
389
 
 
390
static void mainloop_time_free(pa_time_event *e) {
 
391
    pa_assert(e);
 
392
    pa_assert(!e->dead);
 
393
 
 
394
    e->dead = true;
 
395
    e->mainloop->time_events_please_scan ++;
 
396
 
 
397
    if (e->enabled) {
 
398
        pa_assert(e->mainloop->n_enabled_time_events > 0);
 
399
        e->mainloop->n_enabled_time_events--;
 
400
        e->enabled = false;
 
401
    }
 
402
 
 
403
    if (e->mainloop->cached_next_time_event == e)
 
404
        e->mainloop->cached_next_time_event = NULL;
 
405
 
 
406
    /* no wakeup needed here. Think about it! */
 
407
}
 
408
 
 
409
static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) {
 
410
    pa_assert(e);
 
411
    pa_assert(!e->dead);
 
412
 
 
413
    e->destroy_callback = callback;
 
414
}
 
415
 
 
416
/* quit() */
 
417
 
 
418
static void mainloop_quit(pa_mainloop_api *a, int retval) {
 
419
    pa_mainloop *m;
 
420
 
 
421
    pa_assert(a);
 
422
    pa_assert(a->userdata);
 
423
    m = a->userdata;
 
424
    pa_assert(a == &m->api);
 
425
 
 
426
    pa_mainloop_quit(m, retval);
 
427
}
 
428
 
 
429
static const pa_mainloop_api vtable = {
 
430
    .userdata = NULL,
 
431
 
 
432
    .io_new = mainloop_io_new,
 
433
    .io_enable = mainloop_io_enable,
 
434
    .io_free = mainloop_io_free,
 
435
    .io_set_destroy = mainloop_io_set_destroy,
 
436
 
 
437
    .time_new = mainloop_time_new,
 
438
    .time_restart = mainloop_time_restart,
 
439
    .time_free = mainloop_time_free,
 
440
    .time_set_destroy = mainloop_time_set_destroy,
 
441
 
 
442
    .defer_new = mainloop_defer_new,
 
443
    .defer_enable = mainloop_defer_enable,
 
444
    .defer_free = mainloop_defer_free,
 
445
    .defer_set_destroy = mainloop_defer_set_destroy,
 
446
 
 
447
    .quit = mainloop_quit,
 
448
};
 
449
 
 
450
pa_mainloop *pa_mainloop_new(void) {
 
451
    pa_mainloop *m;
 
452
 
 
453
    pa_init_i18n();
 
454
 
 
455
    m = pa_xnew0(pa_mainloop, 1);
 
456
 
 
457
    if (pa_pipe_cloexec(m->wakeup_pipe) < 0) {
 
458
        pa_log_error("ERROR: cannot create wakeup pipe");
 
459
        pa_xfree(m);
 
460
        return NULL;
 
461
    }
 
462
 
 
463
    pa_make_fd_nonblock(m->wakeup_pipe[0]);
 
464
    pa_make_fd_nonblock(m->wakeup_pipe[1]);
 
465
 
 
466
    m->rebuild_pollfds = true;
 
467
 
 
468
    m->api = vtable;
 
469
    m->api.userdata = m;
 
470
 
 
471
    m->state = STATE_PASSIVE;
 
472
 
 
473
    m->poll_func_ret = -1;
 
474
 
 
475
    return m;
 
476
}
 
477
 
 
478
static void cleanup_io_events(pa_mainloop *m, bool force) {
 
479
    pa_io_event *e, *n;
 
480
 
 
481
    PA_LLIST_FOREACH_SAFE(e, n, m->io_events) {
 
482
 
 
483
        if (!force && m->io_events_please_scan <= 0)
 
484
            break;
 
485
 
 
486
        if (force || e->dead) {
 
487
            PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
 
488
 
 
489
            if (e->dead) {
 
490
                pa_assert(m->io_events_please_scan > 0);
 
491
                m->io_events_please_scan--;
 
492
            }
 
493
 
 
494
            if (e->destroy_callback)
 
495
                e->destroy_callback(&m->api, e, e->userdata);
 
496
 
 
497
            pa_xfree(e);
 
498
 
 
499
            m->rebuild_pollfds = true;
 
500
        }
 
501
    }
 
502
 
 
503
    pa_assert(m->io_events_please_scan == 0);
 
504
}
 
505
 
 
506
static void cleanup_time_events(pa_mainloop *m, bool force) {
 
507
    pa_time_event *e, *n;
 
508
 
 
509
    PA_LLIST_FOREACH_SAFE(e, n, m->time_events) {
 
510
 
 
511
        if (!force && m->time_events_please_scan <= 0)
 
512
            break;
 
513
 
 
514
        if (force || e->dead) {
 
515
            PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
 
516
 
 
517
            if (e->dead) {
 
518
                pa_assert(m->time_events_please_scan > 0);
 
519
                m->time_events_please_scan--;
 
520
            }
 
521
 
 
522
            if (!e->dead && e->enabled) {
 
523
                pa_assert(m->n_enabled_time_events > 0);
 
524
                m->n_enabled_time_events--;
 
525
                e->enabled = false;
 
526
            }
 
527
 
 
528
            if (e->destroy_callback)
 
529
                e->destroy_callback(&m->api, e, e->userdata);
 
530
 
 
531
            pa_xfree(e);
 
532
        }
 
533
    }
 
534
 
 
535
    pa_assert(m->time_events_please_scan == 0);
 
536
}
 
537
 
 
538
static void cleanup_defer_events(pa_mainloop *m, bool force) {
 
539
    pa_defer_event *e, *n;
 
540
 
 
541
    PA_LLIST_FOREACH_SAFE(e, n, m->defer_events) {
 
542
 
 
543
        if (!force && m->defer_events_please_scan <= 0)
 
544
            break;
 
545
 
 
546
        if (force || e->dead) {
 
547
            PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
 
548
 
 
549
            if (e->dead) {
 
550
                pa_assert(m->defer_events_please_scan > 0);
 
551
                m->defer_events_please_scan--;
 
552
            }
 
553
 
 
554
            if (!e->dead && e->enabled) {
 
555
                pa_assert(m->n_enabled_defer_events > 0);
 
556
                m->n_enabled_defer_events--;
 
557
                e->enabled = false;
 
558
            }
 
559
 
 
560
            if (e->destroy_callback)
 
561
                e->destroy_callback(&m->api, e, e->userdata);
 
562
 
 
563
            pa_xfree(e);
 
564
        }
 
565
    }
 
566
 
 
567
    pa_assert(m->defer_events_please_scan == 0);
 
568
}
 
569
 
 
570
void pa_mainloop_free(pa_mainloop *m) {
 
571
    pa_assert(m);
 
572
 
 
573
    cleanup_io_events(m, true);
 
574
    cleanup_defer_events(m, true);
 
575
    cleanup_time_events(m, true);
 
576
 
 
577
    pa_xfree(m->pollfds);
 
578
 
 
579
    pa_close_pipe(m->wakeup_pipe);
 
580
 
 
581
    pa_xfree(m);
 
582
}
 
583
 
 
584
static void scan_dead(pa_mainloop *m) {
 
585
    pa_assert(m);
 
586
 
 
587
    if (m->io_events_please_scan)
 
588
        cleanup_io_events(m, false);
 
589
 
 
590
    if (m->time_events_please_scan)
 
591
        cleanup_time_events(m, false);
 
592
 
 
593
    if (m->defer_events_please_scan)
 
594
        cleanup_defer_events(m, false);
 
595
}
 
596
 
 
597
static void rebuild_pollfds(pa_mainloop *m) {
 
598
    pa_io_event*e;
 
599
    struct pollfd *p;
 
600
    unsigned l;
 
601
 
 
602
    l = m->n_io_events + 1;
 
603
    if (m->max_pollfds < l) {
 
604
        l *= 2;
 
605
        m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
 
606
        m->max_pollfds = l;
 
607
    }
 
608
 
 
609
    m->n_pollfds = 0;
 
610
    p = m->pollfds;
 
611
 
 
612
    m->pollfds[0].fd = m->wakeup_pipe[0];
 
613
    m->pollfds[0].events = POLLIN;
 
614
    m->pollfds[0].revents = 0;
 
615
    p++;
 
616
    m->n_pollfds++;
 
617
 
 
618
    PA_LLIST_FOREACH(e, m->io_events) {
 
619
        if (e->dead) {
 
620
            e->pollfd = NULL;
 
621
            continue;
 
622
        }
 
623
 
 
624
        e->pollfd = p;
 
625
        p->fd = e->fd;
 
626
        p->events = map_flags_to_libc(e->events);
 
627
        p->revents = 0;
 
628
 
 
629
        p++;
 
630
        m->n_pollfds++;
 
631
    }
 
632
 
 
633
    m->rebuild_pollfds = false;
 
634
}
 
635
 
 
636
static unsigned dispatch_pollfds(pa_mainloop *m) {
 
637
    pa_io_event *e;
 
638
    unsigned r = 0, k;
 
639
 
 
640
    pa_assert(m->poll_func_ret > 0);
 
641
 
 
642
    k = m->poll_func_ret;
 
643
 
 
644
    PA_LLIST_FOREACH(e, m->io_events) {
 
645
 
 
646
        if (k <= 0 || m->quit)
 
647
            break;
 
648
 
 
649
        if (e->dead || !e->pollfd || !e->pollfd->revents)
 
650
            continue;
 
651
 
 
652
        pa_assert(e->pollfd->fd == e->fd);
 
653
        pa_assert(e->callback);
 
654
 
 
655
        e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
 
656
        e->pollfd->revents = 0;
 
657
        r++;
 
658
        k--;
 
659
    }
 
660
 
 
661
    return r;
 
662
}
 
663
 
 
664
static unsigned dispatch_defer(pa_mainloop *m) {
 
665
    pa_defer_event *e;
 
666
    unsigned r = 0;
 
667
 
 
668
    if (m->n_enabled_defer_events <= 0)
 
669
        return 0;
 
670
 
 
671
    PA_LLIST_FOREACH(e, m->defer_events) {
 
672
 
 
673
        if (m->quit)
 
674
            break;
 
675
 
 
676
        if (e->dead || !e->enabled)
 
677
            continue;
 
678
 
 
679
        pa_assert(e->callback);
 
680
        e->callback(&m->api, e, e->userdata);
 
681
        r++;
 
682
    }
 
683
 
 
684
    return r;
 
685
}
 
686
 
 
687
static pa_time_event* find_next_time_event(pa_mainloop *m) {
 
688
    pa_time_event *t, *n = NULL;
 
689
    pa_assert(m);
 
690
 
 
691
    if (m->cached_next_time_event)
 
692
        return m->cached_next_time_event;
 
693
 
 
694
    PA_LLIST_FOREACH(t, m->time_events) {
 
695
 
 
696
        if (t->dead || !t->enabled)
 
697
            continue;
 
698
 
 
699
        if (!n || t->time < n->time) {
 
700
            n = t;
 
701
 
 
702
            /* Shortcut for time == 0 */
 
703
            if (n->time == 0)
 
704
                break;
 
705
        }
 
706
    }
 
707
 
 
708
    m->cached_next_time_event = n;
 
709
    return n;
 
710
}
 
711
 
 
712
static pa_usec_t calc_next_timeout(pa_mainloop *m) {
 
713
    pa_time_event *t;
 
714
    pa_usec_t clock_now;
 
715
 
 
716
    if (m->n_enabled_time_events <= 0)
 
717
        return PA_USEC_INVALID;
 
718
 
 
719
    pa_assert_se(t = find_next_time_event(m));
 
720
 
 
721
    if (t->time <= 0)
 
722
        return 0;
 
723
 
 
724
    clock_now = pa_rtclock_now();
 
725
 
 
726
    if (t->time <= clock_now)
 
727
        return 0;
 
728
 
 
729
    return t->time - clock_now;
 
730
}
 
731
 
 
732
static unsigned dispatch_timeout(pa_mainloop *m) {
 
733
    pa_time_event *e;
 
734
    pa_usec_t now;
 
735
    unsigned r = 0;
 
736
    pa_assert(m);
 
737
 
 
738
    if (m->n_enabled_time_events <= 0)
 
739
        return 0;
 
740
 
 
741
    now = pa_rtclock_now();
 
742
 
 
743
    PA_LLIST_FOREACH(e, m->time_events) {
 
744
 
 
745
        if (m->quit)
 
746
            break;
 
747
 
 
748
        if (e->dead || !e->enabled)
 
749
            continue;
 
750
 
 
751
        if (e->time <= now) {
 
752
            struct timeval tv;
 
753
            pa_assert(e->callback);
 
754
 
 
755
            /* Disable time event */
 
756
            mainloop_time_restart(e, NULL);
 
757
 
 
758
            e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, e->use_rtclock), e->userdata);
 
759
 
 
760
            r++;
 
761
        }
 
762
    }
 
763
 
 
764
    return r;
 
765
}
 
766
 
 
767
void pa_mainloop_wakeup(pa_mainloop *m) {
 
768
    char c = 'W';
 
769
    pa_assert(m);
 
770
 
 
771
    if (pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type) < 0)
 
772
        /* Not many options for recovering from the error. Let's at least log something. */
 
773
        pa_log("pa_write() failed while trying to wake up the mainloop: %s", pa_cstrerror(errno));
 
774
}
 
775
 
 
776
static void clear_wakeup(pa_mainloop *m) {
 
777
    char c[10];
 
778
 
 
779
    pa_assert(m);
 
780
 
 
781
    while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c))
 
782
        ;
 
783
}
 
784
 
 
785
int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
 
786
    pa_assert(m);
 
787
    pa_assert(m->state == STATE_PASSIVE);
 
788
 
 
789
    clear_wakeup(m);
 
790
    scan_dead(m);
 
791
 
 
792
    if (m->quit)
 
793
        goto quit;
 
794
 
 
795
    if (m->n_enabled_defer_events <= 0) {
 
796
 
 
797
        if (m->rebuild_pollfds)
 
798
            rebuild_pollfds(m);
 
799
 
 
800
        m->prepared_timeout = calc_next_timeout(m);
 
801
        if (timeout >= 0) {
 
802
            uint64_t u = (uint64_t) timeout * PA_USEC_PER_MSEC;
 
803
 
 
804
            if (u < m->prepared_timeout || m->prepared_timeout == PA_USEC_INVALID)
 
805
                m->prepared_timeout = timeout;
 
806
        }
 
807
    }
 
808
 
 
809
    m->state = STATE_PREPARED;
 
810
    return 0;
 
811
 
 
812
quit:
 
813
    m->state = STATE_QUIT;
 
814
    return -2;
 
815
}
 
816
 
 
817
static int usec_to_timeout(pa_usec_t u) {
 
818
    int timeout;
 
819
 
 
820
    if (u == PA_USEC_INVALID)
 
821
        return -1;
 
822
 
 
823
    timeout = (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC;
 
824
    pa_assert(timeout >= 0);
 
825
 
 
826
    return timeout;
 
827
}
 
828
 
 
829
int pa_mainloop_poll(pa_mainloop *m) {
 
830
    pa_assert(m);
 
831
    pa_assert(m->state == STATE_PREPARED);
 
832
 
 
833
    if (m->quit)
 
834
        goto quit;
 
835
 
 
836
    m->state = STATE_POLLING;
 
837
 
 
838
    if (m->n_enabled_defer_events)
 
839
        m->poll_func_ret = 0;
 
840
    else {
 
841
        pa_assert(!m->rebuild_pollfds);
 
842
 
 
843
        if (m->poll_func)
 
844
            m->poll_func_ret = m->poll_func(
 
845
                    m->pollfds, m->n_pollfds,
 
846
                    usec_to_timeout(m->prepared_timeout),
 
847
                    m->poll_func_userdata);
 
848
        else {
 
849
#ifdef HAVE_PPOLL
 
850
            struct timespec ts;
 
851
 
 
852
            m->poll_func_ret = ppoll(
 
853
                    m->pollfds, m->n_pollfds,
 
854
                    m->prepared_timeout == PA_USEC_INVALID ? NULL : pa_timespec_store(&ts, m->prepared_timeout),
 
855
                    NULL);
 
856
#else
 
857
            m->poll_func_ret = pa_poll(
 
858
                    m->pollfds, m->n_pollfds,
 
859
                    usec_to_timeout(m->prepared_timeout));
 
860
#endif
 
861
        }
 
862
 
 
863
        if (m->poll_func_ret < 0) {
 
864
            if (errno == EINTR)
 
865
                m->poll_func_ret = 0;
 
866
            else
 
867
                pa_log("poll(): %s", pa_cstrerror(errno));
 
868
        }
 
869
    }
 
870
 
 
871
    m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
 
872
    return m->poll_func_ret;
 
873
 
 
874
quit:
 
875
    m->state = STATE_QUIT;
 
876
    return -2;
 
877
}
 
878
 
 
879
int pa_mainloop_dispatch(pa_mainloop *m) {
 
880
    unsigned dispatched = 0;
 
881
 
 
882
    pa_assert(m);
 
883
    pa_assert(m->state == STATE_POLLED);
 
884
 
 
885
    if (m->quit)
 
886
        goto quit;
 
887
 
 
888
    if (m->n_enabled_defer_events)
 
889
        dispatched += dispatch_defer(m);
 
890
    else {
 
891
        if (m->n_enabled_time_events)
 
892
            dispatched += dispatch_timeout(m);
 
893
 
 
894
        if (m->quit)
 
895
            goto quit;
 
896
 
 
897
        if (m->poll_func_ret > 0)
 
898
            dispatched += dispatch_pollfds(m);
 
899
    }
 
900
 
 
901
    if (m->quit)
 
902
        goto quit;
 
903
 
 
904
    m->state = STATE_PASSIVE;
 
905
 
 
906
    return (int) dispatched;
 
907
 
 
908
quit:
 
909
    m->state = STATE_QUIT;
 
910
    return -2;
 
911
}
 
912
 
 
913
int pa_mainloop_get_retval(pa_mainloop *m) {
 
914
    pa_assert(m);
 
915
 
 
916
    return m->retval;
 
917
}
 
918
 
 
919
int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
 
920
    int r;
 
921
    pa_assert(m);
 
922
 
 
923
    if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
 
924
        goto quit;
 
925
 
 
926
    if ((r = pa_mainloop_poll(m)) < 0)
 
927
        goto quit;
 
928
 
 
929
    if ((r = pa_mainloop_dispatch(m)) < 0)
 
930
        goto quit;
 
931
 
 
932
    return r;
 
933
 
 
934
quit:
 
935
 
 
936
    if ((r == -2) && retval)
 
937
        *retval = pa_mainloop_get_retval(m);
 
938
    return r;
 
939
}
 
940
 
 
941
int pa_mainloop_run(pa_mainloop *m, int *retval) {
 
942
    int r;
 
943
 
 
944
    while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0)
 
945
        ;
 
946
 
 
947
    if (r == -2)
 
948
        return 1;
 
949
    else
 
950
        return -1;
 
951
}
 
952
 
 
953
void pa_mainloop_quit(pa_mainloop *m, int retval) {
 
954
    pa_assert(m);
 
955
 
 
956
    m->quit = true;
 
957
    m->retval = retval;
 
958
    pa_mainloop_wakeup(m);
 
959
}
 
960
 
 
961
pa_mainloop_api* pa_mainloop_get_api(pa_mainloop *m) {
 
962
    pa_assert(m);
 
963
 
 
964
    return &m->api;
 
965
}
 
966
 
 
967
void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
 
968
    pa_assert(m);
 
969
 
 
970
    m->poll_func = poll_func;
 
971
    m->poll_func_userdata = userdata;
 
972
}
 
973
 
 
974
bool pa_mainloop_is_our_api(pa_mainloop_api *m) {
 
975
    pa_assert(m);
 
976
 
 
977
    return m->io_new == mainloop_io_new;
 
978
}