s4/tests: Implement a blackbox test for 'samba-tool drs' command
[Samba.git] / lib / tevent / tevent_liboop.c
blob3d36b0e2a15847adcfee94c74b87af76e56ae4fb
1 /*
2 Unix SMB/CIFS implementation.
3 main select loop and event handling
4 wrapper for http://liboop.org/
6 Copyright (C) Stefan Metzmacher 2005
8 ** NOTE! The following LGPL license applies to the tevent
9 ** library. This does NOT imply that all of Samba is released
10 ** under the LGPL
12 This library is free software; you can redistribute it and/or
13 modify it under the terms of the GNU Lesser General Public
14 License as published by the Free Software Foundation; either
15 version 3 of the License, or (at your option) any later version.
17 This library is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public
23 License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include "events.h"
27 #include "events_internal.h"
29 #include <oop.h>
32 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
34 NOTE: this code compiles fine, but is completely *UNTESTED*
35 and is only committed as an example
37 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
40 static int oop_event_context_destructor(struct tevent_context *ev)
42 oop_source_sys *oop_sys = ev->additional_data;
44 oop_sys_delete(oop_sys);
46 return 0;
50 create a oop_event_context structure.
52 static int oop_event_context_init(struct tevent_context *ev, void *private_data)
54 oop_source_sys *oop_sys = private_data;
56 if (!oop_sys) {
57 oop_sys = oop_sys_new();
58 if (!oop_sys) {
59 return -1;
62 talloc_set_destructor(ev, oop_event_context_destructor);
65 ev->additional_data = oop_sys;
67 return 0;
70 static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
72 struct tevent_fd *fde = ptr;
74 if (fd != fde->fd) return OOP_ERROR;
76 switch(oop_type) {
77 case OOP_READ:
78 fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data);
79 return OOP_CONTINUE;
80 case OOP_WRITE:
81 fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data);
82 return OOP_CONTINUE;
83 case OOP_EXCEPTION:
84 return OOP_ERROR;
85 case OOP_NUM_EVENTS:
86 return OOP_ERROR;
89 return OOP_ERROR;
93 destroy an fd_event
95 static int oop_event_fd_destructor(struct tevent_fd *fde)
97 struct tevent_context *ev = fde->event_ctx;
98 oop_source_sys *oop_sys = ev->additional_data;
99 oop_source *oop = oop_sys_source(oop_sys);
101 if (fde->flags & EVENT_FD_READ)
102 oop->cancel_fd(oop, fde->fd, OOP_READ);
103 if (fde->flags & EVENT_FD_WRITE)
104 oop->cancel_fd(oop, fde->fd, OOP_WRITE);
106 if (fde->flags & EVENT_FD_AUTOCLOSE) {
107 close(fde->fd);
108 fde->fd = -1;
111 return 0;
115 add a fd based event
116 return NULL on failure (memory allocation error)
118 static struct tevent_fd *oop_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
119 int fd, uint16_t flags,
120 event_fd_handler_t handler,
121 void *private_data)
123 struct tevent_fd *fde;
124 oop_source_sys *oop_sys = ev->additional_data;
125 oop_source *oop = oop_sys_source(oop_sys);
127 fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
128 if (!fde) return NULL;
130 fde->event_ctx = ev;
131 fde->fd = fd;
132 fde->flags = flags;
133 fde->handler = handler;
134 fde->private_data = private_data;
135 fde->additional_flags = 0;
136 fde->additional_data = NULL;
138 if (fde->flags & EVENT_FD_READ)
139 oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
140 if (fde->flags & EVENT_FD_WRITE)
141 oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
143 talloc_set_destructor(fde, oop_event_fd_destructor);
145 return fde;
149 return the fd event flags
151 static uint16_t oop_event_get_fd_flags(struct tevent_fd *fde)
153 return fde->flags;
157 set the fd event flags
159 static void oop_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
161 oop_source_sys *oop_sys;
162 oop_source *oop;
164 oop_sys = fde->event_ctx->additional_data;
165 oop = oop_sys_source(oop_sys);
167 if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
168 oop->cancel_fd(oop, fde->fd, OOP_READ);
170 if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ))
171 oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
173 if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
174 oop->cancel_fd(oop, fde->fd, OOP_WRITE);
176 if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE))
177 oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
179 fde->flags = flags;
182 static int oop_event_timed_destructor(struct tevent_timer *te);
184 static int oop_event_timed_deny_destructor(struct tevent_timer *te)
186 return -1;
189 static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
191 struct tevent_timer *te = ptr;
193 /* deny the handler to free the event */
194 talloc_set_destructor(te, oop_event_timed_deny_destructor);
195 te->handler(te->event_ctx, te, t, te->private_data);
197 talloc_set_destructor(te, oop_event_timed_destructor);
198 talloc_free(te);
200 return OOP_CONTINUE;
204 destroy a timed event
206 static int oop_event_timed_destructor(struct tevent_timer *te)
208 struct tevent_context *ev = te->event_ctx;
209 oop_source_sys *oop_sys = ev->additional_data;
210 oop_source *oop = oop_sys_source(oop_sys);
212 oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
214 return 0;
218 add a timed event
219 return NULL on failure (memory allocation error)
221 static struct tevent_timer *oop_event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
222 struct timeval next_event,
223 event_timed_handler_t handler,
224 void *private_data)
226 oop_source_sys *oop_sys = ev->additional_data;
227 oop_source *oop = oop_sys_source(oop_sys);
228 struct tevent_timer *te;
230 te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer);
231 if (te == NULL) return NULL;
233 te->event_ctx = ev;
234 te->next_event = next_event;
235 te->handler = handler;
236 te->private_data = private_data;
237 te->additional_data = NULL;
239 oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
241 talloc_set_destructor(te, oop_event_timed_destructor);
243 return te;
247 do a single event loop using the events defined in ev
249 static int oop_event_loop_once(struct tevent_context *ev)
251 void *oop_ret;
252 oop_source_sys *oop_sys = ev->additional_data;
254 oop_ret = oop_sys_run_once(oop_sys);
255 if (oop_ret == OOP_CONTINUE) {
256 return 0;
259 return -1;
263 return on failure or (with 0) if all fd events are removed
265 static int oop_event_loop_wait(struct tevent_context *ev)
267 void *oop_ret;
268 oop_source_sys *oop_sys = ev->additional_data;
270 oop_ret = oop_sys_run(oop_sys);
271 if (oop_ret == OOP_CONTINUE) {
272 return 0;
275 return -1;
278 static const struct event_ops event_oop_ops = {
279 .context_init = oop_event_context_init,
280 .add_fd = oop_event_add_fd,
281 .get_fd_flags = oop_event_get_fd_flags,
282 .set_fd_flags = oop_event_set_fd_flags,
283 .add_timer = oop_event_add_timed,
284 .add_signal = common_event_add_signal,
285 .loop_once = oop_event_loop_once,
286 .loop_wait = oop_event_loop_wait,
289 const struct event_ops *event_liboop_get_ops(void)
291 return &event_oop_ops;