8 struct pa_subscription
{
11 void (*callback
)(struct pa_core
*c
, enum pa_subscription_event_type t
, uint32_t index
, void *userdata
);
13 enum pa_subscription_mask mask
;
15 struct pa_subscription
*prev
, *next
;
18 struct pa_subscription_event
{
19 enum pa_subscription_event_type type
;
23 static void sched_event(struct pa_core
*c
);
25 struct pa_subscription
* pa_subscription_new(struct pa_core
*c
, enum pa_subscription_mask m
, void (*callback
)(struct pa_core
*c
, enum pa_subscription_event_type t
, uint32_t index
, void *userdata
), void *userdata
) {
26 struct pa_subscription
*s
;
29 s
= pa_xmalloc(sizeof(struct pa_subscription
));
32 s
->callback
= callback
;
33 s
->userdata
= userdata
;
36 if ((s
->next
= c
->subscriptions
))
43 void pa_subscription_free(struct pa_subscription
*s
) {
44 assert(s
&& !s
->dead
);
49 static void free_item(struct pa_subscription
*s
) {
53 s
->prev
->next
= s
->next
;
55 s
->core
->subscriptions
= s
->next
;
58 s
->next
->prev
= s
->prev
;
63 void pa_subscription_free_all(struct pa_core
*c
) {
64 struct pa_subscription_event
*e
;
67 while (c
->subscriptions
)
68 free_item(c
->subscriptions
);
70 if (c
->subscription_event_queue
) {
71 while ((e
= pa_queue_pop(c
->subscription_event_queue
)))
74 pa_queue_free(c
->subscription_event_queue
, NULL
, NULL
);
75 c
->subscription_event_queue
= NULL
;
78 if (c
->subscription_defer_event
) {
79 c
->mainloop
->defer_free(c
->subscription_defer_event
);
80 c
->subscription_defer_event
= NULL
;
84 static void defer_cb(struct pa_mainloop_api
*m
, struct pa_defer_event
*e
, void *userdata
) {
85 struct pa_core
*c
= userdata
;
86 struct pa_subscription
*s
;
87 assert(c
&& c
->subscription_defer_event
== e
&& c
->mainloop
== m
);
89 c
->mainloop
->defer_enable(c
->subscription_defer_event
, 0);
92 /* Dispatch queued events */
94 if (c
->subscription_event_queue
) {
95 struct pa_subscription_event
*e
;
97 while ((e
= pa_queue_pop(c
->subscription_event_queue
))) {
98 struct pa_subscription
*s
;
100 for (s
= c
->subscriptions
; s
; s
= s
->next
) {
101 if (!s
->dead
&& pa_subscription_match_flags(s
->mask
, e
->type
))
102 s
->callback(c
, e
->type
, e
->index
, s
->userdata
);
109 /* Remove dead subscriptions */
111 s
= c
->subscriptions
;
113 struct pa_subscription
*n
= s
->next
;
120 static void sched_event(struct pa_core
*c
) {
123 if (!c
->subscription_defer_event
) {
124 c
->subscription_defer_event
= c
->mainloop
->defer_new(c
->mainloop
, defer_cb
, c
);
125 assert(c
->subscription_defer_event
);
128 c
->mainloop
->defer_enable(c
->subscription_defer_event
, 1);
132 void pa_subscription_post(struct pa_core
*c
, enum pa_subscription_event_type t
, uint32_t index
) {
133 struct pa_subscription_event
*e
;
136 e
= pa_xmalloc(sizeof(struct pa_subscription_event
));
140 if (!c
->subscription_event_queue
) {
141 c
->subscription_event_queue
= pa_queue_new();
142 assert(c
->subscription_event_queue
);
145 pa_queue_push(c
->subscription_event_queue
, e
);
150 int pa_subscription_match_flags(enum pa_subscription_mask m
, enum pa_subscription_event_type t
) {
151 return !!(m
& (1 >> (t
& PA_SUBSCRIPTION_EVENT_FACILITY_MASK
)));