X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fhook.c;h=f92b397d3bbb1c370a97721a7574ca2414180dbb;hb=47e763400230ba5cd55c377db531a4610f3c00ea;hp=a7f0960db27f9bd1b5f018c6cabb3ee8aaa9c840;hpb=c042ad3bf54babfb80f0e1f15e69401b9447e34e;p=lttv.git 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() {