Annotation of embedaddon/bird/lib/event.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD Library -- Event Processing
3: *
4: * (c) 1999 Martin Mares <mj@ucw.cz>
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: /**
10: * DOC: Events
11: *
12: * Events are there to keep track of deferred execution.
13: * Since BIRD is single-threaded, it requires long lasting tasks to be split to smaller
14: * parts, so that no module can monopolize the CPU. To split such a task, just create
15: * an &event resource, point it to the function you want to have called and call ev_schedule()
16: * to ask the core to run the event when nothing more important requires attention.
17: *
18: * You can also define your own event lists (the &event_list structure), enqueue your
19: * events in them and explicitly ask to run them.
20: */
21:
22: #include "nest/bird.h"
23: #include "lib/event.h"
24:
25: event_list global_event_list;
26:
27: inline void
28: ev_postpone(event *e)
29: {
30: if (ev_active(e))
31: {
32: rem_node(&e->n);
33: e->n.next = NULL;
34: }
35: }
36:
37: static void
38: ev_dump(resource *r)
39: {
40: event *e = (event *) r;
41:
42: debug("(code %p, data %p, %s)\n",
43: e->hook,
44: e->data,
45: e->n.next ? "scheduled" : "inactive");
46: }
47:
48: static struct resclass ev_class = {
49: "Event",
50: sizeof(event),
51: (void (*)(resource *)) ev_postpone,
52: ev_dump,
53: NULL,
54: NULL
55: };
56:
57: /**
58: * ev_new - create a new event
59: * @p: resource pool
60: *
61: * This function creates a new event resource. To use it,
62: * you need to fill the structure fields and call ev_schedule().
63: */
64: event *
65: ev_new(pool *p)
66: {
67: event *e = ralloc(p, &ev_class);
68: return e;
69: }
70:
71: /**
72: * ev_run - run an event
73: * @e: an event
74: *
75: * This function explicitly runs the event @e (calls its hook
76: * function) and removes it from an event list if it's linked to any.
77: *
78: * From the hook function, you can call ev_enqueue() or ev_schedule()
79: * to re-add the event.
80: */
81: inline void
82: ev_run(event *e)
83: {
84: ev_postpone(e);
85: e->hook(e->data);
86: }
87:
88: /**
89: * ev_enqueue - enqueue an event
90: * @l: an event list
91: * @e: an event
92: *
93: * ev_enqueue() stores the event @e to the specified event
94: * list @l which can be run by calling ev_run_list().
95: */
96: inline void
97: ev_enqueue(event_list *l, event *e)
98: {
99: ev_postpone(e);
100: add_tail(l, &e->n);
101: }
102:
103: /**
104: * ev_schedule - schedule an event
105: * @e: an event
106: *
107: * This function schedules an event by enqueueing it to a system-wide
108: * event list which is run by the platform dependent code whenever
109: * appropriate.
110: */
111: void
112: ev_schedule(event *e)
113: {
114: ev_enqueue(&global_event_list, e);
115: }
116:
117: void io_log_event(void *hook, void *data);
118:
119: /**
120: * ev_run_list - run an event list
121: * @l: an event list
122: *
123: * This function calls ev_run() for all events enqueued in the list @l.
124: */
125: int
126: ev_run_list(event_list *l)
127: {
128: node *n;
129: list tmp_list;
130:
131: init_list(&tmp_list);
132: add_tail_list(&tmp_list, l);
133: init_list(l);
134: WALK_LIST_FIRST(n, tmp_list)
135: {
136: event *e = SKIP_BACK(event, n, n);
137:
138: /* This is ugly hack, we want to log just events executed from the main I/O loop */
139: if (l == &global_event_list)
140: io_log_event(e->hook, e->data);
141:
142: ev_run(e);
143: }
144: return !EMPTY_LIST(*l);
145: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>