r25522: Convert to standard bool types.
[Samba.git] / source / lib / events / events.c
blob464d65ef797a444c3d36d80cab961e3606a0d965
1 /*
2 Unix SMB/CIFS implementation.
3 main select loop and event handling
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 PLEASE READ THIS BEFORE MODIFYING!
23 This module is a general abstraction for the main select loop and
24 event handling. Do not ever put any localised hacks in here, instead
25 register one of the possible event types and implement that event
26 somewhere else.
28 There are 2 types of event handling that are handled in this module:
30 1) a file descriptor becoming readable or writeable. This is mostly
31 used for network sockets, but can be used for any type of file
32 descriptor. You may only register one handler for each file
33 descriptor/io combination or you will get unpredictable results
34 (this means that you can have a handler for read events, and a
35 separate handler for write events, but not two handlers that are
36 both handling read events)
38 2) a timed event. You can register an event that happens at a
39 specific time. You can register as many of these as you
40 like. They are single shot - add a new timed event in the event
41 handler to get another event.
43 To setup a set of events you first need to create a event_context
44 structure using the function event_context_init(); This returns a
45 'struct event_context' that you use in all subsequent calls.
47 After that you can add/remove events that you are interested in
48 using event_add_*() and talloc_free()
50 Finally, you call event_loop_wait_once() to block waiting for one of the
51 events to occor or event_loop_wait() which will loop
52 forever.
56 #include "includes.h"
57 #include "lib/events/events.h"
58 #include "lib/events/events_internal.h"
59 #include "lib/util/dlinklist.h"
60 #include "param/param.h"
61 #if _SAMBA_BUILD_
62 #include "build.h"
63 #endif
65 struct event_ops_list {
66 struct event_ops_list *next, *prev;
67 const char *name;
68 const struct event_ops *ops;
71 /* list of registered event backends */
72 static struct event_ops_list *event_backends;
74 static char *event_default_backend = NULL;
77 register an events backend
79 bool event_register_backend(const char *name, const struct event_ops *ops)
81 struct event_ops_list *e;
82 e = talloc(talloc_autofree_context(), struct event_ops_list);
83 if (e == NULL) return false;
84 e->name = name;
85 e->ops = ops;
86 DLIST_ADD(event_backends, e);
87 return true;
91 set the default event backend
93 void event_set_default_backend(const char *backend)
95 if (event_default_backend) free(event_default_backend);
96 event_default_backend = strdup(backend);
100 initialise backends if not already done
102 static void event_backend_init(void)
104 #if _SAMBA_BUILD_
105 init_module_fn static_init[] = STATIC_LIBEVENTS_MODULES;
106 init_module_fn *shared_init;
107 if (event_backends) return;
108 shared_init = load_samba_modules(NULL, global_loadparm, "LIBEVENTS");
109 run_init_functions(static_init);
110 run_init_functions(shared_init);
111 #else
112 bool events_standard_init(void);
113 bool events_select_init(void);
114 events_select_init();
115 events_standard_init();
116 #if HAVE_EVENTS_EPOLL
118 bool events_epoll_init(void);
119 events_epoll_init();
121 #endif
122 #endif
126 list available backends
128 const char **event_backend_list(TALLOC_CTX *mem_ctx)
130 const char **list = NULL;
131 struct event_ops_list *e;
133 event_backend_init();
135 for (e=event_backends;e;e=e->next) {
136 list = str_list_add(list, e->name);
139 talloc_steal(mem_ctx, list);
141 return list;
145 create a event_context structure for a specific implemementation.
146 This must be the first events call, and all subsequent calls pass
147 this event_context as the first element. Event handlers also
148 receive this as their first argument.
150 This function is for allowing third-party-applications to hook in gluecode
151 to their own event loop code, so that they can make async usage of our client libs
153 NOTE: use event_context_init() inside of samba!
155 static struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx,
156 const struct event_ops *ops)
158 struct event_context *ev;
159 int ret;
161 ev = talloc_zero(mem_ctx, struct event_context);
162 if (!ev) return NULL;
164 ev->ops = ops;
166 ret = ev->ops->context_init(ev);
167 if (ret != 0) {
168 talloc_free(ev);
169 return NULL;
172 return ev;
176 create a event_context structure. This must be the first events
177 call, and all subsequent calls pass this event_context as the first
178 element. Event handlers also receive this as their first argument.
180 struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name)
182 struct event_ops_list *e;
184 event_backend_init();
186 #if _SAMBA_BUILD_
187 if (name == NULL) {
188 name = lp_parm_string(global_loadparm, NULL, "event", "backend");
190 #endif
191 if (name == NULL) {
192 name = event_default_backend;
194 if (name == NULL) {
195 name = "standard";
198 for (e=event_backends;e;e=e->next) {
199 if (strcmp(name, e->name) == 0) {
200 return event_context_init_ops(mem_ctx, e->ops);
203 return NULL;
208 create a event_context structure. This must be the first events
209 call, and all subsequent calls pass this event_context as the first
210 element. Event handlers also receive this as their first argument.
212 struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
214 return event_context_init_byname(mem_ctx, NULL);
218 add a fd based event
219 return NULL on failure (memory allocation error)
221 if flags contains EVENT_FD_AUTOCLOSE then the fd will be closed when
222 the returned fd_event context is freed
224 struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
225 int fd, uint16_t flags, event_fd_handler_t handler,
226 void *private_data)
228 return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
232 add a disk aio event
234 struct aio_event *event_add_aio(struct event_context *ev,
235 TALLOC_CTX *mem_ctx,
236 struct iocb *iocb,
237 event_aio_handler_t handler,
238 void *private_data)
240 if (ev->ops->add_aio == NULL) return NULL;
241 return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data);
245 return the fd event flags
247 uint16_t event_get_fd_flags(struct fd_event *fde)
249 if (!fde) return 0;
250 return fde->event_ctx->ops->get_fd_flags(fde);
254 set the fd event flags
256 void event_set_fd_flags(struct fd_event *fde, uint16_t flags)
258 if (!fde) return;
259 fde->event_ctx->ops->set_fd_flags(fde, flags);
263 add a timed event
264 return NULL on failure
266 struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
267 struct timeval next_event,
268 event_timed_handler_t handler,
269 void *private_data)
271 return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
275 add a signal event
277 sa_flags are flags to sigaction(2)
279 return NULL on failure
281 struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx,
282 int signum,
283 int sa_flags,
284 event_signal_handler_t handler,
285 void *private_data)
287 return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data);
291 do a single event loop using the events defined in ev
293 _PUBLIC_ int event_loop_once(struct event_context *ev)
295 return ev->ops->loop_once(ev);
299 return on failure or (with 0) if all fd events are removed
301 int event_loop_wait(struct event_context *ev)
303 return ev->ops->loop_wait(ev);
307 find an event context that is a parent of the given memory context,
308 or create a new event context as a child of the given context if
309 none is found
311 This should be used in preference to event_context_init() in places
312 where you would prefer to use the existing event context if possible
313 (which is most situations)
315 struct event_context *event_context_find(TALLOC_CTX *mem_ctx)
317 struct event_context *ev = talloc_find_parent_bytype(mem_ctx, struct event_context);
318 if (ev == NULL) {
319 ev = event_context_init(mem_ctx);
321 return ev;