Hooks by priority
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 25 May 2004 18:42:26 +0000 (18:42 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 25 May 2004 18:42:26 +0000 (18:42 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@541 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/lttv/lttv/hook.c
ltt/branches/poly/lttv/lttv/hook.h

index a7f0960db27f9bd1b5f018c6cabb3ee8aaa9c840..f92b397d3bbb1c370a97721a7574ca2414180dbb 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,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() 
 {
index 803304c0e3606fa99bb19b272377bc7623a67379..bd68e0966304b2af1ce455fbb8a85d29fc915762 100644 (file)
@@ -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 */
 
This page took 0.027486 seconds and 4 git commands to generate.