Statistics
| Branch: | Revision:

iof-bird-daemon / lib / event.c @ 9b136840

History | View | Annotate | Download (2.94 KB)

1 3b15402f Martin Mares
/*
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 525fa2c1 Martin Mares
/**
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 58f7d004 Martin Mares
 * to ask the core to run the event when nothing more important requires attention.
17 525fa2c1 Martin Mares
 *
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 3b15402f Martin Mares
#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 6f8bbaa1 Ondrej Zajicek
  if (ev_active(e))
31 3b15402f Martin Mares
    {
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 67bd949a Martin Mares
  sizeof(event),
51 3b15402f Martin Mares
  (void (*)(resource *)) ev_postpone,
52 e81b440f Ondrej Zajicek
  ev_dump,
53 acb60628 Ondrej Zajicek
  NULL,
54 e81b440f Ondrej Zajicek
  NULL
55 3b15402f Martin Mares
};
56
57 525fa2c1 Martin Mares
/**
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 3b15402f Martin Mares
event *
65
ev_new(pool *p)
66
{
67
  event *e = ralloc(p, &ev_class);
68
  return e;
69
}
70
71 525fa2c1 Martin Mares
/**
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 8f6accb5 Martin Mares
inline void
82 3b15402f Martin Mares
ev_run(event *e)
83
{
84 8f6accb5 Martin Mares
  ev_postpone(e);
85
  e->hook(e->data);
86 3b15402f Martin Mares
}
87
88 525fa2c1 Martin Mares
/**
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 3b15402f Martin Mares
inline void
97
ev_enqueue(event_list *l, event *e)
98
{
99 8f6accb5 Martin Mares
  ev_postpone(e);
100 3b15402f Martin Mares
  add_tail(l, &e->n);
101
}
102
103 525fa2c1 Martin Mares
/**
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 3b15402f Martin Mares
void
112
ev_schedule(event *e)
113
{
114
  ev_enqueue(&global_event_list, e);
115
}
116
117 8bcb5fb1 Ondrej Zajicek
void io_log_event(void *hook, void *data);
118
119 525fa2c1 Martin Mares
/**
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 84a7d7f7 Martin Mares
int
126 3b15402f Martin Mares
ev_run_list(event_list *l)
127
{
128 b933281e Ondrej Zajicek
  node *n;
129 8f6accb5 Martin Mares
  list tmp_list;
130 0d70292d Martin Mares
131 8f6accb5 Martin Mares
  init_list(&tmp_list);
132
  add_tail_list(&tmp_list, l);
133
  init_list(l);
134 b933281e Ondrej Zajicek
  WALK_LIST_FIRST(n, tmp_list)
135 3b15402f Martin Mares
    {
136 0d70292d Martin Mares
      event *e = SKIP_BACK(event, n, n);
137 8bcb5fb1 Ondrej Zajicek
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 ebc793a5 Martin Mares
      ev_run(e);
143 3b15402f Martin Mares
    }
144 ebc793a5 Martin Mares
  return !EMPTY_LIST(*l);
145 3b15402f Martin Mares
}