From 47e763400230ba5cd55c377db531a4610f3c00ea Mon Sep 17 00:00:00 2001 From: compudj Date: Tue, 25 May 2004 18:42:26 +0000 Subject: [PATCH] Hooks by priority git-svn-id: http://ltt.polymtl.ca/svn@541 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/lttv/lttv/hook.c | 131 +++++++++++++++++++++++++++-- ltt/branches/poly/lttv/lttv/hook.h | 37 ++++++-- 2 files changed, 156 insertions(+), 12 deletions(-) diff --git a/ltt/branches/poly/lttv/lttv/hook.c b/ltt/branches/poly/lttv/lttv/hook.c index a7f0960d..f92b397d 100644 --- a/ltt/branches/poly/lttv/lttv/hook.c +++ b/ltt/branches/poly/lttv/lttv/hook.c @@ -21,10 +21,18 @@ typedef struct _LttvHookClosure { - LttvHook hook; - void *hook_data; + LttvHook hook; + void *hook_data; + LttvHookPrio prio; } LttvHookClosure; +gint lttv_hooks_prio_compare(LttvHookClosure *a, LttvHookClosure *b) +{ + if(a->prio < b->prio) return -1; + if(a->prio > b->prio) return 1; + return 0; +} + LttvHooks *lttv_hooks_new() { @@ -39,7 +47,7 @@ void lttv_hooks_destroy(LttvHooks *h) } -void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) +void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p) { LttvHookClosure c; @@ -47,7 +55,9 @@ void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) c.hook = f; c.hook_data = hook_data; + c.prio = p; g_array_append_val(h,c); + g_array_sort(h, (GCompareFunc)lttv_hooks_prio_compare); } @@ -59,6 +69,7 @@ void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) for(i = 0 ; i < list->len; i++) { g_array_append_val(h,g_array_index(list, LttvHookClosure, i)); } + g_array_sort(h, (GCompareFunc)lttv_hooks_prio_compare); } @@ -133,13 +144,23 @@ unsigned lttv_hooks_number(LttvHooks *h) } -void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data) +void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data, + LttvHookPrio *p) { LttvHookClosure *c; + if(i >= h->len) + { + *f = NULL; + *hook_data = NULL; + *p = 0; + return; + } + c = &g_array_index(h, LttvHookClosure, i); *f = c->hook; *hook_data = c->hook_data; + *p = c->prio; } @@ -148,7 +169,6 @@ void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i) g_array_remove_index(h, i); } - gboolean lttv_hooks_call(LttvHooks *h, void *call_data) { gboolean ret, sum_ret = FALSE; @@ -181,6 +201,107 @@ gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data) return FALSE; } +gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1, + LttvHooks *h2, void *call_data2) +{ + gboolean ret, sum_ret = FALSE; + + LttvHookClosure *c1, *c2; + + guint i, j; + + if(h1 != NULL && h2 != NULL) { + for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) { + c1 = &g_array_index(h1, LttvHookClosure, i); + c2 = &g_array_index(h2, LttvHookClosure, j); + if(c1->prio <= c2->prio) { + ret = c1->hook(c1->hook_data,call_data1); + sum_ret = sum_ret || ret; + i++; + } + else { + ret = c2->hook(c2->hook_data,call_data2); + sum_ret = sum_ret || ret; + j++; + } + } + /* Finish the last list with hooks left */ + for(;i < h1->len; i++) { + c1 = &g_array_index(h1, LttvHookClosure, i); + ret = c1->hook(c1->hook_data,call_data1); + sum_ret = sum_ret || ret; + } + for(;j < h2->len; j++) { + c2 = &g_array_index(h2, LttvHookClosure, j); + ret = c2->hook(c2->hook_data,call_data2); + sum_ret = sum_ret || ret; + } + } + else if(h1 != NULL && h2 == NULL) { + for(i = 0 ; i < h1->len ; i++) { + c1 = &g_array_index(h1, LttvHookClosure, i); + ret = c1->hook(c1->hook_data,call_data1); + sum_ret = sum_ret || ret; + } + } + else if(h1 == NULL && h2 != NULL) { + for(j = 0 ; j < h2->len ; j++) { + c2 = &g_array_index(h2, LttvHookClosure, j); + ret = c2->hook(c2->hook_data,call_data2); + sum_ret = sum_ret || ret; + } + } + + return sum_ret; +} + +gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1, + LttvHooks *h2, void *call_data2) +{ + LttvHookClosure *c1, *c2; + + guint i, j; + + if(h1 != NULL && h2 != NULL) { + for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) { + c1 = &g_array_index(h1, LttvHookClosure, i); + c2 = &g_array_index(h2, LttvHookClosure, j); + if(c1->prio <= c2->prio) { + if(c1->hook(c1->hook_data,call_data1)) return TRUE; + i++; + } + else { + if(c2->hook(c2->hook_data,call_data2)) return TRUE; + j++; + } + } + /* Finish the last list with hooks left */ + for(;i < h1->len; i++) { + c1 = &g_array_index(h1, LttvHookClosure, i); + if(c1->hook(c1->hook_data,call_data1)) return TRUE; + } + for(;j < h2->len; j++) { + c2 = &g_array_index(h2, LttvHookClosure, j); + if(c2->hook(c2->hook_data,call_data2)) return TRUE; + } + } + else if(h1 != NULL && h2 == NULL) { + for(i = 0 ; i < h1->len ; i++) { + c1 = &g_array_index(h1, LttvHookClosure, i); + if(c1->hook(c1->hook_data,call_data1)) return TRUE; + } + } + else if(h1 == NULL && h2 != NULL) { + for(j = 0 ; j < h2->len ; j++) { + c2 = &g_array_index(h2, LttvHookClosure, j); + if(c2->hook(c2->hook_data,call_data2)) return TRUE; + } + } + + return FALSE; + +} + LttvHooksById *lttv_hooks_by_id_new() { diff --git a/ltt/branches/poly/lttv/lttv/hook.h b/ltt/branches/poly/lttv/lttv/hook.h index 803304c0..bd68e096 100644 --- a/ltt/branches/poly/lttv/lttv/hook.h +++ b/ltt/branches/poly/lttv/lttv/hook.h @@ -1,6 +1,8 @@ /* This file is part of the Linux Trace Toolkit viewer * Copyright (C) 2003-2004 Michel Dagenais * + * 25/05/2004 Mathieu Desnoyers : Hook priorities + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation; @@ -32,6 +34,15 @@ typedef gboolean (*LttvHook)(void *hook_data, void *call_data); typedef GArray LttvHooks; +/* A priority associated with each hook, from -19 (high prio) to 20 (low prio) + * 0 being the default priority. + * + * Priority ordering is done in the lttv_hooks_add and lttv_hooks_add_list + * functions. Hook removal does not change list order. + */ + +#define LTTV_PRIO_DEFAULT 0 +typedef gint LttvHookPrio; /* Create and destroy a list of hooks */ @@ -42,7 +53,7 @@ void lttv_hooks_destroy(LttvHooks *h); /* Add a hook and its hook data to the list */ -void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data); +void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p); /* Add a list of hooks to the list h */ @@ -62,7 +73,7 @@ void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data); /* Remove a list of hooks from the hooks list in h. */ -void lttv_hooks_remove_data_list(LttvHooks *h, LttvHook *list); +void lttv_hooks_remove_data_list(LttvHooks *h, LttvHooks *list); /* Return the number of hooks in the list */ @@ -70,9 +81,11 @@ void lttv_hooks_remove_data_list(LttvHooks *h, LttvHook *list); unsigned lttv_hooks_number(LttvHooks *h); -/* Return the hook at the specified position in the list */ +/* Return the hook at the specified position in the list. + * *f and *hook_data are NULL if no hook exists at that position. */ -void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data); +void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data, + LttvHookPrio *p); /* Remove the specified hook. The position of the following hooks may change */ @@ -81,17 +94,27 @@ void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i); /* Call all the hooks in the list, each with its hook data, - with the specified call data. Return TRUE if one hook returned TRUE. */ + with the specified call data, in priority order. Return TRUE if one hook + returned TRUE. */ gboolean lttv_hooks_call(LttvHooks *h, void *call_data); -/* Call the hooks in the list until one returns true, in which case TRUE is - returned. */ +/* Call the hooks in the list in priority order until one returns true, + * in which case TRUE is returned. */ gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data); +/* Call hooks from two lists in priority order. If priority is the same, + * hooks from h1 are called first. */ + +gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1, + LttvHooks *h2, void *call_data2); + +gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1, + LttvHooks *h2, void *call_data2); + /* Sometimes different hooks need to be called based on the case. The case is represented by an unsigned integer id */ -- 2.34.1