shl: hook: add helpers to add callbacks only once
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 13 Jan 2013 10:23:05 +0000 (11:23 +0100)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 13 Jan 2013 10:26:05 +0000 (11:26 +0100)
Very often we want to avoid adding callbacks multiple times. Currently we
have to keep track of this in each module with a boolean value.
To simplify this procedure, we add helpers that guarantee that entries are
only added once and a helper to remove all entries with a given cb+data
combination.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
src/shl_hook.h

index aa35eb3..73afbb5 100644 (file)
@@ -129,6 +129,24 @@ static inline int shl_hook_add(struct shl_hook *hook, shl_hook_cb cb,
        return 0;
 }
 
+static inline int shl_hook_add_single(struct shl_hook *hook, shl_hook_cb cb,
+                                     void *data)
+{
+       struct shl_hook_entry *entry;
+       struct shl_dlist *iter;
+
+       if (!hook || !cb)
+               return -EINVAL;
+
+       shl_dlist_for_each(iter, &hook->entries) {
+               entry = shl_dlist_entry(iter, struct shl_hook_entry, list);
+               if (entry->cb == cb && entry->data == data)
+                       return 0;
+       }
+
+       return shl_hook_add(hook, cb, data);
+}
+
 static inline void shl_hook_rm(struct shl_hook *hook, shl_hook_cb cb,
                               void *data)
 {
@@ -152,6 +170,28 @@ static inline void shl_hook_rm(struct shl_hook *hook, shl_hook_cb cb,
        }
 }
 
+static inline void shl_hook_rm_all(struct shl_hook *hook, shl_hook_cb cb,
+                                  void *data)
+{
+       struct shl_dlist *iter, *tmp;
+       struct shl_hook_entry *entry;
+
+       if (!hook || !cb)
+               return;
+
+       shl_dlist_for_each_reverse_safe(iter, tmp, &hook->entries) {
+               entry = shl_dlist_entry(iter, struct shl_hook_entry, list);
+               if (entry->cb == cb && entry->data == data) {
+                       /* if *_call() is running we must not disturb it */
+                       if (hook->cur_entry == iter)
+                               hook->cur_entry = iter->next;
+                       shl_dlist_unlink(&entry->list);
+                       free(entry);
+                       hook->num--;
+               }
+       }
+}
+
 static inline void shl_hook_call(struct shl_hook *hook, void *parent,
                                 void *arg)
 {