1 #ifndef foopulsertpollhfoo
2 #define foopulsertpollhfoo
5 This file is part of PulseAudio.
7 Copyright 2004-2006 Lennart Poettering
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as
11 published by the Free Software Foundation; either version 2.1 of the
12 License, or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 #include <sys/types.h>
28 #include <pulse/sample.h>
29 #include <pulsecore/asyncmsgq.h>
30 #include <pulsecore/fdsem.h>
31 #include <pulsecore/macro.h>
33 /* An implementation of a "real-time" poll loop. Basically, this is
34 * yet another wrapper around poll(). However it has certain
35 * advantages over pa_mainloop and suchlike:
37 * 1) It uses timer_create() and POSIX real time signals to guarantee
38 * optimal high-resolution timing. Starting with Linux 2.6.21 hrtimers
39 * are available, and since right now only nanosleep() and the POSIX
40 * clock and timer interfaces have been ported to hrtimers (and not
41 * ppoll/pselect!) we have to combine ppoll() with timer_create(). The
42 * fact that POSIX timers and POSIX rt signals are used internally is
45 * 2) It allows raw access to the pollfd data to users
47 * 3) It allows arbitrary functions to be run before entering the
48 * actual poll() and after it.
50 * Only a single interval timer is supported..*/
52 typedef struct pa_rtpoll pa_rtpoll;
53 typedef struct pa_rtpoll_item pa_rtpoll_item;
55 typedef enum pa_rtpoll_priority {
56 PA_RTPOLL_EARLY = -100, /* For veeery important stuff, like handling control messages */
57 PA_RTPOLL_NORMAL = 0, /* For normal stuff */
58 PA_RTPOLL_LATE = +100, /* For housekeeping */
59 PA_RTPOLL_NEVER = INT_MAX, /* For stuff that doesn't register any callbacks, but only fds to listen on */
60 } pa_rtpoll_priority_t;
62 pa_rtpoll *pa_rtpoll_new(void);
63 void pa_rtpoll_free(pa_rtpoll *p);
65 /* Sleep on the rtpoll until the time event, or any of the fd events
66 * is triggered. If "wait" is 0 we don't sleep but only update the
67 * struct pollfd. Returns negative on error, positive if the loop
68 * should continue to run, 0 when the loop should be terminated
70 int pa_rtpoll_run(pa_rtpoll *f, pa_bool_t wait);
72 void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, pa_usec_t usec);
73 void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec);
74 void pa_rtpoll_set_timer_disabled(pa_rtpoll *p);
76 /* Return TRUE when the elapsed timer was the reason for
77 * the last pa_rtpoll_run() invocation to finish */
78 pa_bool_t pa_rtpoll_timer_elapsed(pa_rtpoll *p);
80 /* A new fd wakeup item for pa_rtpoll */
81 pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds);
82 void pa_rtpoll_item_free(pa_rtpoll_item *i);
84 /* Please note that this pointer might change on every call and when
85 * pa_rtpoll_run() is called. Hence: call this immediately before
86 * using the pointer and don't save the result anywhere */
87 struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds);
89 /* Set the callback that shall be called when there's time to do some work: If the
90 * callback returns a value > 0, the poll is skipped and the next
91 * iteraton of the loop will start immediately. */
92 void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i));
94 /* Set the callback that shall be called immediately before entering
95 * the sleeping poll: If the callback returns a value > 0, the poll is
96 * skipped and the next iteraton of the loop will start
98 void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i));
100 /* Set the callback that shall be called immediately after having
101 * entered the sleeping poll */
102 void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i));
104 void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata);
105 void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i);
107 pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *s);
108 pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q);
109 pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q);
111 /* Requests the loop to exit. Will cause the next iteration of
112 * pa_rtpoll_run() to return 0 */
113 void pa_rtpoll_quit(pa_rtpoll *p);