]> code.delx.au - pulseaudio/blob - src/pulsecore/hook-list.c
rework hook list stuff again, and replace macros with real functins. We loose type...
[pulseaudio] / src / pulsecore / hook-list.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #include <pulsecore/hook-list.h>
23
24 void pa_hook_init(pa_hook *hook) {
25 assert(hook);
26
27 PA_LLIST_HEAD_INIT(pa_hook_slots, hook->slots);
28 hook->last = NULL;
29 hook->n_dead = hook->firing = 0;
30 }
31
32 static void slot_free(pa_hook *hook, pa_hook_slot *slot) {
33 assert(hook);
34 assert(slot);
35
36 if (hook->last == slot)
37 hook->last = slot->prev;
38
39 PA_LLIST_REMOVE(pa_hook_slot, hook->slots, slot);
40
41 pa_xfree(slot);
42 }
43
44 void pa_hook_free(pa_hook *hook) {
45 assert(hook);
46 assert(!hook->firing);
47
48 while (hook->slots)
49 slot_free(hook, hook->slots);
50
51 pa_hook_init(hook);
52 }
53
54 pa_hook_slot* pa_hook_connect(pa_hook *hook, pa_hook_cb_t cb, void *userdata) {
55 pa_hook_slot *slot;
56
57 assert(cb);
58
59 slot = pa_xnew(pa_hook_slot, 1);
60 slot->hook = hook;
61 slot->dead = 0;
62 slot->callback = cb;
63 slot->userdata = userdata;
64
65 PA_LLIST_INSERT_AFTER(pa_hook_slot, hook->slots, hook->last, slot);
66 hook->last = slot;
67
68 return slot;
69 }
70
71 void pa_hook_slot_free(pa_hook_slot *slot) {
72 assert(slot);
73 assert(!slot->dead);
74
75 if (slot->hook->firing > 0) {
76 slot->dead = 1;
77 slot->hook->n_dead++;
78 } else
79 slot_free(slot->hook, slot);
80 }
81
82 pa_hook_result_t pa_hook_fire(pa_hook *hook, void *data) {
83 pa_hook_slot *slot, *next;
84 pa_hook_result_t result = PA_HOOK_OK;
85
86 assert(hook);
87
88 hook->firing ++;
89
90 for (slot = hook->slots; slot; slot = slot->next) {
91 if (slot->dead)
92 continue;
93
94 if ((result = slot->callback(data, slot->userdata)) != PA_HOOK_OK)
95 break;
96 }
97
98 hook->firing --;
99
100 for (slot = hook->slots; hook->n_dead > 0 && slot; slot = next) {
101 next = slot->next;
102
103 if (slot->dead) {
104 slot_free(hook, slot);
105 hook->n_dead--;
106 }
107 }
108
109 return result;
110 }
111