minor fix
[lttv.git] / ltt / branches / poly / lttv / lttv / hook.c
CommitLineData
9c312311 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
ffd54a90 19
3d218f2a 20#include <lttv/hook.h>
eccb5352 21
22
dc877563 23typedef struct _LttvHookClosure {
47e76340 24 LttvHook hook;
25 void *hook_data;
26 LttvHookPrio prio;
dc877563 27} LttvHookClosure;
eccb5352 28
47e76340 29gint lttv_hooks_prio_compare(LttvHookClosure *a, LttvHookClosure *b)
30{
31 if(a->prio < b->prio) return -1;
32 if(a->prio > b->prio) return 1;
33 return 0;
34}
35
eccb5352 36
dc877563 37LttvHooks *lttv_hooks_new()
38{
39 return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure));
eccb5352 40}
41
dc877563 42
43void lttv_hooks_destroy(LttvHooks *h)
44{
2a2fa4f0 45 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "lttv_hooks_destroy()");
eccb5352 46 g_array_free(h, TRUE);
47}
48
eccb5352 49
47e76340 50void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p)
dc877563 51{
52 LttvHookClosure c;
53
54 if(h == NULL)g_error("Null hook added");
eccb5352 55
56 c.hook = f;
57 c.hook_data = hook_data;
47e76340 58 c.prio = p;
eccb5352 59 g_array_append_val(h,c);
47e76340 60 g_array_sort(h, (GCompareFunc)lttv_hooks_prio_compare);
eccb5352 61}
62
63
dc877563 64void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list)
65{
66 guint i;
67
ffd54a90 68 if(list == NULL) return;
dc877563 69 for(i = 0 ; i < list->len; i++) {
70 g_array_append_val(h,g_array_index(list, LttvHookClosure, i));
71 }
47e76340 72 g_array_sort(h, (GCompareFunc)lttv_hooks_prio_compare);
dc877563 73}
74
75
76void *lttv_hooks_remove(LttvHooks *h, LttvHook f)
77{
78 unsigned i;
79
80 void *hook_data;
81
82 LttvHookClosure *c;
83
84 for(i = 0 ; i < h->len ; i++) {
85 c = &g_array_index(h, LttvHookClosure, i);
86 if(c->hook == f) {
87 hook_data = c->hook_data;
88 lttv_hooks_remove_by_position(h, i);
89 return hook_data;
90 }
91 }
92 return NULL;
93}
94
95
96void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data)
eccb5352 97{
dc877563 98 unsigned i;
99
100 LttvHookClosure *c;
eccb5352 101
102 for(i = 0 ; i < h->len ; i++) {
dc877563 103 c = &g_array_index(h, LttvHookClosure, i);
104 if(c->hook == f && c->hook_data == hook_data) {
105 lttv_hooks_remove_by_position(h, i);
106 return;
107 }
108 }
109}
110
111
112void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list)
113{
114 guint i, j;
115
116 LttvHookClosure *c, *c_list;
117
ffd54a90 118 if(list == NULL) return;
dc877563 119 for(i = 0, j = 0 ; i < h->len && j < list->len ;) {
120 c = &g_array_index(h, LttvHookClosure, i);
121 c_list = &g_array_index(list, LttvHookClosure, j);
122 if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) {
123 lttv_hooks_remove_by_position(h, i);
124 j++;
125 }
126 else i++;
127 }
128
129 /* Normally the hooks in h are ordered as in list. If this is not the case,
130 try harder here. */
131
132 if(j < list->len) {
133 for(; j < list->len ; j++) {
134 c_list = &g_array_index(list, LttvHookClosure, j);
135 lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data);
136 }
eccb5352 137 }
138}
139
140
dc877563 141unsigned lttv_hooks_number(LttvHooks *h)
142{
143 return h->len;
144}
eccb5352 145
dc877563 146
47e76340 147void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data,
148 LttvHookPrio *p)
dc877563 149{
150 LttvHookClosure *c;
151
47e76340 152 if(i >= h->len)
153 {
154 *f = NULL;
155 *hook_data = NULL;
156 *p = 0;
157 return;
158 }
159
dc877563 160 c = &g_array_index(h, LttvHookClosure, i);
161 *f = c->hook;
162 *hook_data = c->hook_data;
47e76340 163 *p = c->prio;
dc877563 164}
165
166
ffd54a90 167void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i)
dc877563 168{
ffd54a90 169 g_array_remove_index(h, i);
dc877563 170}
171
dc877563 172gboolean lttv_hooks_call(LttvHooks *h, void *call_data)
173{
b445142a 174 gboolean ret, sum_ret = FALSE;
dc877563 175
176 LttvHookClosure *c;
177
ffd54a90 178 guint i;
179
dc877563 180 if(h != NULL) {
181 for(i = 0 ; i < h->len ; i++) {
182 c = &g_array_index(h, LttvHookClosure, i);
b445142a 183 ret = c->hook(c->hook_data,call_data);
184 sum_ret = sum_ret || ret;
dc877563 185 }
186 }
b445142a 187 return sum_ret;
dc877563 188}
189
190
191gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data)
192{
193 LttvHookClosure *c;
194
ffd54a90 195 guint i;
196
dc877563 197 for(i = 0 ; i < h->len ; i++) {
198 c = &g_array_index(h, LttvHookClosure, i);
199 if(c->hook(c->hook_data,call_data)) return TRUE;
200 }
201 return FALSE;
202}
203
47e76340 204gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
205 LttvHooks *h2, void *call_data2)
206{
207 gboolean ret, sum_ret = FALSE;
208
209 LttvHookClosure *c1, *c2;
210
211 guint i, j;
212
213 if(h1 != NULL && h2 != NULL) {
214 for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) {
215 c1 = &g_array_index(h1, LttvHookClosure, i);
216 c2 = &g_array_index(h2, LttvHookClosure, j);
217 if(c1->prio <= c2->prio) {
218 ret = c1->hook(c1->hook_data,call_data1);
219 sum_ret = sum_ret || ret;
220 i++;
221 }
222 else {
223 ret = c2->hook(c2->hook_data,call_data2);
224 sum_ret = sum_ret || ret;
225 j++;
226 }
227 }
228 /* Finish the last list with hooks left */
229 for(;i < h1->len; i++) {
230 c1 = &g_array_index(h1, LttvHookClosure, i);
231 ret = c1->hook(c1->hook_data,call_data1);
232 sum_ret = sum_ret || ret;
233 }
234 for(;j < h2->len; j++) {
235 c2 = &g_array_index(h2, LttvHookClosure, j);
236 ret = c2->hook(c2->hook_data,call_data2);
237 sum_ret = sum_ret || ret;
238 }
239 }
240 else if(h1 != NULL && h2 == NULL) {
241 for(i = 0 ; i < h1->len ; i++) {
242 c1 = &g_array_index(h1, LttvHookClosure, i);
243 ret = c1->hook(c1->hook_data,call_data1);
244 sum_ret = sum_ret || ret;
245 }
246 }
247 else if(h1 == NULL && h2 != NULL) {
248 for(j = 0 ; j < h2->len ; j++) {
249 c2 = &g_array_index(h2, LttvHookClosure, j);
250 ret = c2->hook(c2->hook_data,call_data2);
251 sum_ret = sum_ret || ret;
252 }
253 }
254
255 return sum_ret;
256}
257
258gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1,
259 LttvHooks *h2, void *call_data2)
260{
261 LttvHookClosure *c1, *c2;
262
263 guint i, j;
264
265 if(h1 != NULL && h2 != NULL) {
266 for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) {
267 c1 = &g_array_index(h1, LttvHookClosure, i);
268 c2 = &g_array_index(h2, LttvHookClosure, j);
269 if(c1->prio <= c2->prio) {
270 if(c1->hook(c1->hook_data,call_data1)) return TRUE;
271 i++;
272 }
273 else {
274 if(c2->hook(c2->hook_data,call_data2)) return TRUE;
275 j++;
276 }
277 }
278 /* Finish the last list with hooks left */
279 for(;i < h1->len; i++) {
280 c1 = &g_array_index(h1, LttvHookClosure, i);
281 if(c1->hook(c1->hook_data,call_data1)) return TRUE;
282 }
283 for(;j < h2->len; j++) {
284 c2 = &g_array_index(h2, LttvHookClosure, j);
285 if(c2->hook(c2->hook_data,call_data2)) return TRUE;
286 }
287 }
288 else if(h1 != NULL && h2 == NULL) {
289 for(i = 0 ; i < h1->len ; i++) {
290 c1 = &g_array_index(h1, LttvHookClosure, i);
291 if(c1->hook(c1->hook_data,call_data1)) return TRUE;
292 }
293 }
294 else if(h1 == NULL && h2 != NULL) {
295 for(j = 0 ; j < h2->len ; j++) {
296 c2 = &g_array_index(h2, LttvHookClosure, j);
297 if(c2->hook(c2->hook_data,call_data2)) return TRUE;
298 }
299 }
300
301 return FALSE;
302
303}
304
dc877563 305
306LttvHooksById *lttv_hooks_by_id_new()
307{
eccb5352 308 return g_ptr_array_new();
309}
310
311
dc877563 312void lttv_hooks_by_id_destroy(LttvHooksById *h)
313{
314 guint i;
315
316 for(i = 0 ; i < h->len ; i++) {
317 if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i]));
318 }
eccb5352 319 g_ptr_array_free(h, TRUE);
320}
321
322
ffd54a90 323LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id)
eccb5352 324{
dc877563 325 if(h->len <= id) g_ptr_array_set_size(h, id + 1);
eccb5352 326 if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new();
dc877563 327 return h->pdata[id];
eccb5352 328}
329
dc877563 330
331unsigned lttv_hooks_by_id_max_id(LttvHooksById *h)
eccb5352 332{
dc877563 333 return h->len;
334}
335
336
337LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id)
338{
339 if(id < h->len) return h->pdata[id];
340 return NULL;
341}
342
343
344void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id)
345{
346 if(id < h->len && h->pdata[id] != NULL) {
347 lttv_hooks_destroy((LttvHooks *)h->pdata[id]);
348 h->pdata[id] = NULL;
349 }
eccb5352 350}
351
This page took 0.041996 seconds and 4 git commands to generate.