X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fhook.c;h=12f121986606473f211a86a533c648f4d2c66e8f;hb=dc87756342c051418eccb2b7d932ffa5453c6788;hp=eb7c5d9f194a302d9d3d0f4f1104320419e460cb;hpb=90b93bd19d886e2d78e798fb29b6bae14343da1e;p=lttv.git diff --git a/ltt/branches/poly/lttv/hook.c b/ltt/branches/poly/lttv/hook.c index eb7c5d9f..12f12198 100644 --- a/ltt/branches/poly/lttv/hook.c +++ b/ltt/branches/poly/lttv/hook.c @@ -1,28 +1,29 @@ #include -typedef struct _lttv_hook_closure { +typedef struct _LttvHookClosure { lttv_hook hook; void *hook_data; -} lttv_hook_closure; +} LttvHookClosure; -inline lttv_hooks *lttv_hooks_new() { - return g_array_new(FALSE, FALSE, sizeof(lttv_hook_closure)); +LttvHooks *lttv_hooks_new() +{ + return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure)); } -/* MD: delete elements of the array also, but don't free pointed addresses - * (functions). - */ -inline void lttv_hooks_destroy(lttv_hooks *h) { + +void lttv_hooks_destroy(LttvHooks *h) +{ g_array_free(h, TRUE); } -inline void lttv_hooks_add(lttv_hooks *h, lttv_hook f, void *hook_data) { - lttv_hook_closure c; - /* if h is null, do nothing, or popup a warning message */ - if(h == NULL)return; +void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) +{ + LttvHookClosure c; + + if(h == NULL)g_error("Null hook added"); c.hook = f; c.hook_data = hook_data; @@ -30,47 +31,173 @@ inline void lttv_hooks_add(lttv_hooks *h, lttv_hook f, void *hook_data) { } -int lttv_hooks_call(lttv_hooks *h, void *call_data) +void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) +{ + guint i; + + for(i = 0 ; i < list->len; i++) { + g_array_append_val(h,g_array_index(list, LttvHookClosure, i)); + } +} + + +void *lttv_hooks_remove(LttvHooks *h, LttvHook f) +{ + unsigned i; + + void *hook_data; + + LttvHookClosure *c; + + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + if(c->hook == f) { + hook_data = c->hook_data; + lttv_hooks_remove_by_position(h, i); + return hook_data; + } + } + return NULL; +} + + +void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data) { - int i; - lttv_hook_closure * c; + unsigned i; + + LttvHookClosure *c; for(i = 0 ; i < h->len ; i++) { - c = ((lttv_hook_closure *)h->data) + i; - if(c != NULL) - c->hook(c->hook_data,call_data); - else - g_critical("NULL hook called\n"); + c = &g_array_index(h, LttvHookClosure, i); + if(c->hook == f && c->hook_data == hook_data) { + lttv_hooks_remove_by_position(h, i); + return; + } + } +} + + +void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list) +{ + guint i, j; + + LttvHookClosure *c, *c_list; + + for(i = 0, j = 0 ; i < h->len && j < list->len ;) { + c = &g_array_index(h, LttvHookClosure, i); + c_list = &g_array_index(list, LttvHookClosure, j); + if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) { + lttv_hooks_remove_by_position(h, i); + j++; + } + else i++; + } + + /* Normally the hooks in h are ordered as in list. If this is not the case, + try harder here. */ + + if(j < list->len) { + for(; j < list->len ; j++) { + c_list = &g_array_index(list, LttvHookClosure, j); + lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data); + } } } -/* Sometimes different hooks need to be called based on the case. The - case is represented by an unsigned integer id and may represent different - event types, for instance. */ +unsigned lttv_hooks_number(LttvHooks *h) +{ + return h->len; +} -inline lttv_hooks_by_id *lttv_hooks_by_id_new() { + +void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data) +{ + LttvHookClosure *c; + + c = &g_array_index(h, LttvHookClosure, i); + *f = c->hook; + *hook_data = c->hook_data; +} + + +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 = FALSE; + + LttvHookClosure *c; + + if(h != NULL) { + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + ret = ret || c->hook(c->hook_data,call_data); + } + } + return ret; +} + + +gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data) +{ + LttvHookClosure *c; + + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + if(c->hook(c->hook_data,call_data)) return TRUE; + } + return FALSE; +} + + +LttvHooksById *lttv_hooks_by_id_new() +{ return g_ptr_array_new(); } -inline void lttv_hooks_by_id_destroy(lttv_hooks_by_id *h) { - /* MD: delete elements of the array also */ +void lttv_hooks_by_id_destroy(LttvHooksById *h) +{ + guint i; + + for(i = 0 ; i < h->len ; i++) { + if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i])); + } g_ptr_array_free(h, TRUE); } -void lttv_hooks_by_id_add(lttv_hooks_by_id *h, lttv_hook f, void *hook_data, - unsigned int id) +LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id); { - if(h->len < id) g_ptr_array_set_size(h, id); + if(h->len <= id) g_ptr_array_set_size(h, id + 1); if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new(); - lttv_hooks_add(h->pdata[id], f, hook_data); + return h->pdata[id]; } -void lttv_hooks_by_id_call(lttv_hooks_by_id *h, void *call_data, unsigned int id) + +unsigned lttv_hooks_by_id_max_id(LttvHooksById *h) { - if(h->len <= id || h->pdata[id] == NULL) return; - lttv_hooks_call(h->pdata[id],call_data); + return h->len; +} + + +LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id) +{ + if(id < h->len) return h->pdata[id]; + return NULL; +} + + +void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id) +{ + if(id < h->len && h->pdata[id] != NULL) { + lttv_hooks_destroy((LttvHooks *)h->pdata[id]); + h->pdata[id] = NULL; + } }