aura  0.1
 All Data Structures Functions Variables Modules Pages
eventloop.c
1 #include <aura/aura.h>
2 #include <aura/private.h>
3 #include <sys/eventfd.h>
4 
5 /* FixMe: The current timeout handling is pretty naive. But let it be so for now */
6 
12 static void eventloop_recalculate_timeouts(struct aura_eventloop *loop)
13 {
14  loop->poll_timeout = 5000;
15  struct aura_node *pos;
16  list_for_each_entry(pos, &loop->nodelist, eventloop_node_list) {
17  if (pos->poll_timeout < loop->poll_timeout)
18  loop->poll_timeout = pos->poll_timeout;
19  }
20  slog(4, SLOG_DEBUG, "Adjusted event poll timeout to %d ms", pos->poll_timeout);
21 }
22 
23 static void eventloop_fd_changed_cb(const struct aura_pollfds *fd, enum aura_fd_action act, void *arg)
24 {
25  struct aura_eventloop *loop = arg;
26  aura_eventsys_backend_fd_action(loop->eventsysdata, fd, act);
27 }
28 
38 void aura_eventloop_add(struct aura_eventloop *loop, struct aura_node *node)
39 {
40  struct aura_eventloop *curloop = aura_eventloop_get_data(node);
41 
42  /* Some sanity checking first */
43  if ((curloop != NULL) && (!curloop->autocreated))
44  BUG(node, "Specified node is already bound to an event-system");
45 
46  if (curloop != NULL) {
47  slog(4, SLOG_DEBUG, "eventloop: Node has an associated auto-created eventsystem, destroying...");
48  aura_eventloop_destroy(curloop);
49  }
50 
51  /* Link our next node into our list and adjust timeouts */
52  list_add_tail(&node->eventloop_node_list, &loop->nodelist);
53  aura_eventloop_set_data(node, loop);
54 
55  if (loop->poll_timeout > node->poll_timeout)
56  loop->poll_timeout = node->poll_timeout;
57 
58  /* Set up our fdaction callback to handle descriptor changes */
59  aura_fd_changed_cb(node, eventloop_fd_changed_cb, loop);
60 }
61 
69 void aura_eventloop_del(struct aura_node *node)
70 {
71  const struct aura_pollfds *fds;
72  int i, count;
73  struct aura_eventloop *loop = aura_eventloop_get_data(node);
74 
75  /* Some sanity checking first */
76  if (loop == NULL)
77  BUG(node, "Specified node is not bound to any eventloop");
78 
79  /* Remove our node from the list */
80  list_del(&node->eventloop_node_list);
81  aura_eventloop_set_data(node, NULL);
82 
83  /* Recalc all timeouts */
84  eventloop_recalculate_timeouts(loop);
85 
86  /* Remove all descriptors from epoll, but keep 'em in the node */
87  count = aura_get_pollfds(node, &fds);
88  for (i=0; i<count; i++)
89  aura_eventsys_backend_fd_action(loop->eventsysdata, &fds[i], AURA_FD_REMOVED);
90 
91  /* Remove our fd_changed callback */
92  aura_fd_changed_cb(node, NULL, NULL);
93 }
94 
95 
102 {
103  struct aura_eventloop *loop = calloc(1, sizeof(*loop));
104 
105  if (!loop)
106  return NULL;
107 
108  loop->poll_timeout = 5000;
109  loop->eventsysdata = aura_eventsys_backend_create(loop);
110  if (!loop->eventsysdata)
111  goto err_free_loop;
112 
113  INIT_LIST_HEAD(&loop->nodelist);
114 
115  /* Just return the loop, we're good */
116  return loop;
117 
118 err_free_loop:
119  free(loop);
120  return NULL;
121 }
122 
128 void *aura_eventloop_vcreate(va_list ap)
129 {
130  struct aura_node *node;
131 
132  struct aura_eventloop *loop = aura_eventloop_create_empty();
133 
134  if (!loop)
135  return NULL;
136 
137  /* Add all our nodes to this loop */
138  while ((node = va_arg(ap, struct aura_node *)))
139  aura_eventloop_add(loop, node);
140 
141  /* Return the loop, we're good */
142  return loop;
143 }
144 
151 void *aura_eventloop_create__(int dummy, ...)
152 {
153  void *ret;
154  va_list ap;
155  va_start(ap, dummy);
156  ret = aura_eventloop_vcreate(ap);
157  va_end(ap);
158  return ret;
159 }
160 
166 void aura_eventloop_destroy(struct aura_eventloop *loop)
167 {
168  struct list_head *pos;
169  struct list_head *tmp;
170 
171  list_for_each_safe(pos, tmp, &loop->nodelist) {
172  struct aura_node *node = list_entry(pos, struct aura_node,
173  eventloop_node_list);
174  aura_eventloop_del(node);
175  }
176 
177  aura_eventsys_backend_destroy(loop->eventsysdata);
178  free(loop);
179 }
180 
187 void aura_handle_events_forever(struct aura_eventloop *loop)
188 {
189  loop->keep_running = 1;
190  while (loop->keep_running)
191  aura_handle_events_timeout(loop, loop->poll_timeout);
192 }
193 
201 void aura_handle_events(struct aura_eventloop *loop)
202 {
203  aura_handle_events_timeout(loop, loop->poll_timeout);
204 }
205 
217 void aura_handle_events_timeout(struct aura_eventloop *loop, int timeout_ms)
218 {
219  struct aura_node *pos;
220  /* Handle any pending events from descriptors */
221  aura_eventsys_backend_wait(loop->eventsysdata, timeout_ms);
222  /* Check if any nodes needs their periodic medicine */
223  list_for_each_entry(pos, &loop->nodelist, eventloop_node_list) {
224  aura_process_node_event(pos, NULL);
225 #ifdef AURA_USE_BUFFER_POOL
226  /* GC: Ditch one last buffer from pool if we have too many */
227  if (pos->num_buffers_in_pool >= pos->gc_threshold) {
228  struct aura_buffer *buf;
229  pos->num_buffers_in_pool--;
230  buf = list_entry(pos->buffer_pool.prev, struct aura_buffer, qentry);
231  list_del(pos->buffer_pool.prev);
232  aura_buffer_destroy(buf);
233  }
234 #endif
235  }
236 }
237 
244 void aura_eventloop_break(struct aura_eventloop *loop)
245 {
246  loop->keep_running = 0;
247  aura_eventloop_interrupt(loop);
248 }
249 
250 
266 void aura_eventloop_interrupt(struct aura_eventloop *loop)
267 {
268  aura_eventsys_backend_interrupt(loop->eventsysdata);
269 }
270 
279 void aura_eventloop_report_event(struct aura_eventloop *loop, struct aura_pollfds *ap)
280 {
281  struct aura_node *node;
282  if (ap) {
283  if (ap->magic != 0xdeadbeaf)
284  BUG(NULL, "bad APFD: %x", ap);
285  node = ap->node;
286  aura_process_node_event(node, ap);
287  } else {
288  list_for_each_entry(node, &loop->nodelist, eventloop_node_list) {
289  aura_process_node_event(node, NULL);
290  }
291  }
292 }
void * aura_eventloop_vcreate(va_list ap)
Definition: eventloop.c:128
void aura_handle_events_forever(struct aura_eventloop *loop)
Definition: eventloop.c:187
void * aura_eventloop_create__(int dummy,...)
Definition: eventloop.c:151
Definition: list.h:61
void aura_eventloop_add(struct aura_eventloop *loop, struct aura_node *node)
Definition: eventloop.c:38
struct list_head qentry
Definition: aura.h:345
void * aura_eventloop_create_empty()
Definition: eventloop.c:101
void aura_handle_events_timeout(struct aura_eventloop *loop, int timeout_ms)
Definition: eventloop.c:217
struct aura_eventloop * aura_eventloop_get_data(struct aura_node *node)
Definition: aura.c:243
void aura_handle_events(struct aura_eventloop *loop)
Definition: eventloop.c:201
void aura_eventloop_destroy(struct aura_eventloop *loop)
Definition: eventloop.c:166
void aura_fd_changed_cb(struct aura_node *node, void(*cb)(const struct aura_pollfds *fd, enum aura_fd_action act, void *arg), void *arg)
Definition: aura.c:275
void aura_eventloop_del(struct aura_node *node)
Definition: eventloop.c:69
void aura_eventloop_break(struct aura_eventloop *loop)
Definition: eventloop.c:244
void aura_buffer_destroy(struct aura_buffer *buf)
Definition: buffer.c:101