Branch data Line data Source code
1 : : /***
2 : : This file is part of PulseAudio.
3 : :
4 : : Copyright 2006 Lennart Poettering
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.1 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 : : #ifdef HAVE_CONFIG_H
23 : : #include <config.h>
24 : : #endif
25 : :
26 : : #include <pulse/xmalloc.h>
27 : :
28 : : #include <pulsecore/macro.h>
29 : :
30 : : #include "hook-list.h"
31 : :
32 : 2 : void pa_hook_init(pa_hook *hook, void *data) {
33 [ - + ]: 2 : pa_assert(hook);
34 : :
35 : 2 : PA_LLIST_HEAD_INIT(pa_hook_slot, hook->slots);
36 : 2 : hook->n_dead = hook->n_firing = 0;
37 : 2 : hook->data = data;
38 : 2 : }
39 : :
40 : 3 : static void slot_free(pa_hook *hook, pa_hook_slot *slot) {
41 [ - + ]: 3 : pa_assert(hook);
42 [ - + ]: 3 : pa_assert(slot);
43 : :
44 [ - + ][ + + ]: 3 : PA_LLIST_REMOVE(pa_hook_slot, hook->slots, slot);
[ - + ][ - + ]
45 : :
46 : 3 : pa_xfree(slot);
47 : 3 : }
48 : :
49 : 1 : void pa_hook_done(pa_hook *hook) {
50 [ - + ]: 1 : pa_assert(hook);
51 [ + - ]: 1 : pa_assert(hook->n_firing == 0);
52 : :
53 [ + + ]: 3 : while (hook->slots)
54 : 2 : slot_free(hook, hook->slots);
55 : :
56 : 1 : pa_hook_init(hook, NULL);
57 : 1 : }
58 : :
59 : 3 : pa_hook_slot* pa_hook_connect(pa_hook *hook, pa_hook_priority_t prio, pa_hook_cb_t cb, void *data) {
60 : : pa_hook_slot *slot, *where, *prev;
61 : :
62 [ - + ]: 3 : pa_assert(cb);
63 : :
64 : 3 : slot = pa_xnew(pa_hook_slot, 1);
65 : 3 : slot->hook = hook;
66 : 3 : slot->dead = FALSE;
67 : 3 : slot->callback = cb;
68 : 3 : slot->data = data;
69 : 3 : slot->priority = prio;
70 : :
71 : 3 : prev = NULL;
72 [ + + ]: 4 : for (where = hook->slots; where; where = where->next) {
73 [ + + ]: 3 : if (prio < where->priority)
74 : : break;
75 : 1 : prev = where;
76 : : }
77 : :
78 [ - + ][ + + ]: 3 : PA_LLIST_INSERT_AFTER(pa_hook_slot, hook->slots, prev, slot);
[ + + ][ + - ]
79 : :
80 : 3 : return slot;
81 : : }
82 : :
83 : 1 : void pa_hook_slot_free(pa_hook_slot *slot) {
84 [ - + ]: 1 : pa_assert(slot);
85 [ - + ]: 1 : pa_assert(!slot->dead);
86 : :
87 [ - + ]: 1 : if (slot->hook->n_firing > 0) {
88 : 0 : slot->dead = TRUE;
89 : 0 : slot->hook->n_dead++;
90 : : } else
91 : 1 : slot_free(slot->hook, slot);
92 : 1 : }
93 : :
94 : 2 : pa_hook_result_t pa_hook_fire(pa_hook *hook, void *data) {
95 : : pa_hook_slot *slot, *next;
96 : 2 : pa_hook_result_t result = PA_HOOK_OK;
97 : :
98 [ - + ]: 2 : pa_assert(hook);
99 : :
100 : 2 : hook->n_firing ++;
101 : :
102 [ + + ]: 7 : PA_LLIST_FOREACH(slot, hook->slots) {
103 [ - + ]: 5 : if (slot->dead)
104 : 0 : continue;
105 : :
106 [ + - ]: 5 : if ((result = slot->callback(hook->data, data, slot->data)) != PA_HOOK_OK)
107 : : break;
108 : : }
109 : :
110 : 2 : hook->n_firing --;
111 [ - + ]: 2 : pa_assert(hook->n_firing >= 0);
112 : :
113 [ - + ]: 2 : for (slot = hook->slots; hook->n_dead > 0 && slot; slot = next) {
114 : 0 : next = slot->next;
115 : :
116 [ # # ]: 0 : if (slot->dead) {
117 : 0 : slot_free(hook, slot);
118 : 0 : hook->n_dead--;
119 : : }
120 : : }
121 : :
122 [ - + ]: 2 : pa_assert(hook->n_dead == 0);
123 : :
124 : 2 : return result;
125 : : }
126 : :
127 : 0 : pa_bool_t pa_hook_is_firing(pa_hook *hook) {
128 [ # # ]: 0 : pa_assert(hook);
129 : :
130 : 0 : return hook->n_firing > 0;
131 : : }
|