X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttv%2Flttv%2Fhook.c;h=ab0f9120cb5eb6c8a814bdbb1f25a4371f560a34;hb=190724cdfc53eeebfd895b594f875b53a72adf37;hp=57dcb04979025e07a539b7b67a0c00f62b01a2ea;hpb=90e19f82bca635a1ba52b8a50b64e484bd19c14f;p=lttv.git diff --git a/lttv/lttv/hook.c b/lttv/lttv/hook.c index 57dcb049..ab0f9120 100644 --- a/lttv/lttv/hook.c +++ b/lttv/lttv/hook.c @@ -21,8 +21,6 @@ #endif #include -#include -#include typedef struct _LttvHookClosure { LttvHook hook; @@ -40,7 +38,7 @@ gint lttv_hooks_prio_compare(LttvHookClosure *a, LttvHookClosure *b) } -LttvHooks *lttv_hooks_new() +LttvHooks *lttv_hooks_new(void) { return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure)); } @@ -193,19 +191,23 @@ void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data) } -void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list) +void lttv_hooks_remove_list(LttvHooks *h, const LttvHooks *list) { guint i, j; LttvHookClosure *c, *c_list; if(list == NULL) return; + g_assert(h != list); + /* This iteration assume that both list are in the same order */ 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) { if(c->ref_count == 1) { + int count = h->len; lttv_hooks_remove_by_position(h, i); + g_assert((count-1) == h->len); } else { g_assert(c->ref_count != 0); c->ref_count--; @@ -393,130 +395,23 @@ gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1, } return FALSE; - -} - -/* Two pointer arrays : - * * one indexed by id for quick search : - * size : max id - * typically 4 bytes * 256 facilities * 10 events = 10kbytes - * * another array that keeps a list of used numbers (for later deletion) - * size : number of ids used. - */ - -LttvHooksById *lttv_hooks_by_id_new() -{ - LttvHooksById *h = g_new(LttvHooksById, 1); - h->index = g_ptr_array_sized_new(PREALLOC_EVENTS); - h->array = g_array_sized_new(FALSE, FALSE, sizeof(guint), PREALLOC_EVENTS); - return h; -} - - -void lttv_hooks_by_id_destroy(LttvHooksById *h) -{ - guint i; - - for(i = 0 ; i < h->array->len ; i++) { - guint index = g_array_index(h->array, guint, i); - if(h->index->pdata[index] != NULL) { /* hook may have been removed */ - lttv_hooks_destroy(h->index->pdata[index]); - h->index->pdata[index] = NULL; /* Must be there in case of - multiple addition of the same index */ - } - } - g_ptr_array_free(h->index, TRUE); - g_array_free(h->array, TRUE); } -/* Optimised for searching an existing hook */ -LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id) -{ - if(unlikely(h->index->len <= id)) g_ptr_array_set_size(h->index, id + 1); - if(unlikely(h->index->pdata[id] == NULL)) { - h->index->pdata[id] = lttv_hooks_new(); - g_array_append_val(h->array, id); - } - return h->index->pdata[id]; -} - -unsigned lttv_hooks_by_id_max_id(LttvHooksById *h) +void lttv_hooks_print(const LttvHooks *h) { - return h->index->len; -} + gboolean ret, sum_ret = FALSE; -/* We don't bother removing the used slot array id : lttv_hooks_by_id_destroy is - * almost never called and is able to deal with used slot repetition. */ -void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id) -{ - if(likely(id < h->index->len && h->index->pdata[id] != NULL)) { - lttv_hooks_destroy((LttvHooks *)h->index->pdata[id]); - h->index->pdata[id] = NULL; - } -} + LttvHookClosure *c; -void lttv_hooks_by_id_copy(LttvHooksById *dest, LttvHooksById *src) -{ guint i; - for(i = 0 ; i < src->array->len ; i++) { - guint index = g_array_index(src->array, guint, i); - LttvHooks *srch = lttv_hooks_by_id_find(src, index); - LttvHooks *desth = lttv_hooks_by_id_find(dest, index); - lttv_hooks_add_list(desth, srch); - } -} - -LttvHooksByIdChannelArray *lttv_hooks_by_id_channel_new(void) -{ - LttvHooksByIdChannelArray *h = g_new(LttvHooksByIdChannelArray, 1); - - h->array = g_array_new(FALSE, FALSE, sizeof(LttvHooksByIdChannel)); - return h; -} - -void lttv_hooks_by_id_channel_destroy(LttvHooksByIdChannelArray *h) -{ - LttvHooksByIdChannel *hid; - int i; - - for (i = 0; i < h->array->len; i++) { - hid = &g_array_index(h->array, LttvHooksByIdChannel, i); - lttv_hooks_by_id_destroy(hid->hooks_by_id); - } - g_array_free(h->array, TRUE); - g_free(h); -} - -static LttvHooksByIdChannel * -lttv_hooks_by_id_channel_find_channel(LttvHooksByIdChannelArray *h, - GQuark channel) -{ - LttvHooksByIdChannel *hid; - int i, found = 0; - - for (i = 0; i < h->array->len; i++) { - hid = &g_array_index(h->array, LttvHooksByIdChannel, i); - if (hid->channel == channel) { - found = 1; - break; + if(likely(h != NULL)) { + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + printf("%p:%i:%i,", c->hook, c->ref_count, c->prio); } + printf("\n"); } - if (!found) { - g_array_set_size(h->array, h->array->len + 1); - hid = &g_array_index(h->array, LttvHooksByIdChannel, h->array->len - 1); - hid->channel = channel; - hid->hooks_by_id = lttv_hooks_by_id_new(); - } - return hid; -} -/* get, or create if not found */ -LttvHooks *lttv_hooks_by_id_channel_find(LttvHooksByIdChannelArray *h, - GQuark channel, guint16 id) -{ - LttvHooksByIdChannel *hid; - hid = lttv_hooks_by_id_channel_find_channel(h, channel); - return lttv_hooks_by_id_find(hid->hooks_by_id, id); }