added config
[nao-ulib.git] / src / notifier.c
blobbac6b22bf0bae8a326b5b025d776ce8ad715877a
1 /*
2 * nao-ulib
3 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>
4 * Subject to the GPL.
5 * Nao-Team HTWK,
6 * Faculty of Computer Science, Mathematics and Natural Sciences,
7 * Leipzig University of Applied Sciences (HTWK Leipzig)
8 */
10 #include <stdint.h>
11 #include <errno.h>
13 #include "notifier.h"
14 #include "comp_x86.h"
17 * Event notification framework based on the idea of the Linux kernel
18 * notification chains by Alan Cox which have originally been written
19 * for event delivery within the networking subsystem.
22 int register_event_hook(struct event_block **head,
23 struct event_block *block)
25 if (!block || !head)
26 return -EINVAL;
27 if (!block->hook)
28 return -EINVAL;
30 while ((*head) != NULL) {
31 if (block->prio > (*head)->prio)
32 break;
34 head = &((*head)->next);
37 block->next = (*head);
38 (*head) = block;
39 barrier();
41 return 0;
44 int register_event_hook_once(struct event_block **head,
45 struct event_block *block)
47 if (!block || !head)
48 return -EINVAL;
49 if (!block->hook)
50 return -EINVAL;
52 while ((*head) != NULL) {
53 if (unlikely(block == (*head)))
54 return -EEXIST;
56 if (block->prio > (*head)->prio)
57 break;
59 head = &((*head)->next);
62 block->next = (*head);
63 (*head) = block;
64 barrier();
66 return 0;
69 int unregister_event_hook(struct event_block **head,
70 struct event_block *block)
72 if (!block || !head)
73 return -EINVAL;
75 while ((*head) != NULL) {
76 if (unlikely(block == (*head))) {
77 (*head) = block->next;
78 barrier();
79 break;
82 head = &((*head)->next);
85 return 0;
88 int call_event_hooks(struct event_block **head, unsigned long event,
89 const void *arg, int *called)
91 int ret = BLOCK_SUCC_DONE;
92 struct event_block *block = *head, *next_block;
94 if (!head || !arg)
95 return -EINVAL;
96 if (called)
97 (*called) = 0;
99 while (block) {
100 next_block = block->next;
102 ret = block->hook(block, event, arg);
103 if (ret & BLOCK_STOP_CHAIN)
104 break;
106 if(called)
107 (*called)++;
109 block = next_block;
112 return ret;