stats fixed for new traceset context API
[lttv.git] / ltt / branches / poly / lttv / lttv / hook.c
index a7f0960db27f9bd1b5f018c6cabb3ee8aaa9c840..183f499a46fd7065ce32c62330e6259470deb88e 100644 (file)
 
 
 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,25 +47,60 @@ 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;
-
+  LttvHookClosure *c, new_c;
+  guint i;
+  
   if(h == NULL)g_error("Null hook added");
 
-  c.hook = f;
-  c.hook_data = hook_data;
-  g_array_append_val(h,c);
+  new_c.hook = f;
+  new_c.hook_data = hook_data;
+  new_c.prio = p;
+  for(i = 0; i < h->len; i++) {
+    
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(new_c.prio < c->prio) {
+      g_array_insert_val(h,i,new_c);
+      return;
+    }
+  }
+  if(i == h->len)
+    g_array_append_val(h,new_c);
 }
 
-
-void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) 
+/* lttv_hooks_add_list
+ *
+ * Adds a sorted list into another sorted list.
+ *
+ * Note : h->len is modified, but only incremented. This assures
+ * its coherence through the function.
+ *
+ * j is an index to the element following the last one added in the
+ * destination array.
+ */
+void lttv_hooks_add_list(LttvHooks *h, const LttvHooks *list) 
 {
-  guint i;
+  guint i,j;
+  LttvHookClosure *c;
+  const LttvHookClosure *new_c;
 
   if(list == NULL) return;
-  for(i = 0 ; i < list->len; i++) {
-    g_array_append_val(h,g_array_index(list, LttvHookClosure, i));
+  for(i = 0, j = 0 ; i < list->len; i++) {
+    new_c = &g_array_index(list, LttvHookClosure, i);
+    while(j < h->len) {
+      c = &g_array_index(h, LttvHookClosure, j);
+      if(new_c->prio < c->prio) {
+        g_array_insert_val(h,j,*new_c);
+        j++;
+        break;
+      }
+      else j++;
+    }
+    if(j == h->len) {
+      g_array_append_val(h,*new_c);
+      j++;
+    }
   }
 }
 
@@ -133,13 +176,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 +201,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 +233,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() 
 {
This page took 0.031082 seconds and 4 git commands to generate.