source: branches/samba-3.5.x/lib/tevent/tevent_liboop.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 7.0 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 main select loop and event handling
4 wrapper for http://liboop.org/
5
6 Copyright (C) Stefan Metzmacher 2005
7
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
11
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.
16
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.
21
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/>.
24*/
25
26#include "events.h"
27#include "events_internal.h"
28
29#include <oop.h>
30
31/*
32 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
33
34 NOTE: this code compiles fine, but is completly *UNTESTED*
35 and is only commited as example
36
37 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
38*/
39
40static int oop_event_context_destructor(struct tevent_context *ev)
41{
42 oop_source_sys *oop_sys = ev->additional_data;
43
44 oop_sys_delete(oop_sys);
45
46 return 0;
47}
48
49/*
50 create a oop_event_context structure.
51*/
52static int oop_event_context_init(struct tevent_context *ev, void *private_data)
53{
54 oop_source_sys *oop_sys = private_data;
55
56 if (!oop_sys) {
57 oop_sys = oop_sys_new();
58 if (!oop_sys) {
59 return -1;
60 }
61
62 talloc_set_destructor(ev, oop_event_context_destructor);
63 }
64
65 ev->additional_data = oop_sys;
66
67 return 0;
68}
69
70static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
71{
72 struct tevent_fd *fde = ptr;
73
74 if (fd != fde->fd) return OOP_ERROR;
75
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;
87 }
88
89 return OOP_ERROR;
90}
91
92/*
93 destroy an fd_event
94*/
95static int oop_event_fd_destructor(struct tevent_fd *fde)
96{
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);
100
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);
105
106 if (fde->flags & EVENT_FD_AUTOCLOSE) {
107 close(fde->fd);
108 fde->fd = -1;
109 }
110
111 return 0;
112}
113
114/*
115 add a fd based event
116 return NULL on failure (memory allocation error)
117*/
118static 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)
122{
123 struct tevent_fd *fde;
124 oop_source_sys *oop_sys = ev->additional_data;
125 oop_source *oop = oop_sys_source(oop_sys);
126
127 fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
128 if (!fde) return NULL;
129
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;
137
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);
142
143 talloc_set_destructor(fde, oop_event_fd_destructor);
144
145 return fde;
146}
147
148/*
149 return the fd event flags
150*/
151static uint16_t oop_event_get_fd_flags(struct tevent_fd *fde)
152{
153 return fde->flags;
154}
155
156/*
157 set the fd event flags
158*/
159static void oop_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
160{
161 oop_source_sys *oop_sys;
162 oop_source *oop;
163
164 oop_sys = fde->event_ctx->additional_data;
165 oop = oop_sys_source(oop_sys);
166
167 if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
168 oop->cancel_fd(oop, fde->fd, OOP_READ);
169
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);
172
173 if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
174 oop->cancel_fd(oop, fde->fd, OOP_WRITE);
175
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);
178
179 fde->flags = flags;
180}
181
182static int oop_event_timed_destructor(struct tevent_timer *te);
183
184static int oop_event_timed_deny_destructor(struct tevent_timer *te)
185{
186 return -1;
187}
188
189static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
190{
191 struct tevent_timer *te = ptr;
192
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);
196
197 talloc_set_destructor(te, oop_event_timed_destructor);
198 talloc_free(te);
199
200 return OOP_CONTINUE;
201}
202
203/*
204 destroy a timed event
205*/
206static int oop_event_timed_destructor(struct tevent_timer *te)
207{
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);
211
212 oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
213
214 return 0;
215}
216
217/*
218 add a timed event
219 return NULL on failure (memory allocation error)
220*/
221static 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)
225{
226 oop_source_sys *oop_sys = ev->additional_data;
227 oop_source *oop = oop_sys_source(oop_sys);
228 struct tevent_timer *te;
229
230 te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer);
231 if (te == NULL) return NULL;
232
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;
238
239 oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
240
241 talloc_set_destructor(te, oop_event_timed_destructor);
242
243 return te;
244}
245
246/*
247 do a single event loop using the events defined in ev
248*/
249static int oop_event_loop_once(struct tevent_context *ev)
250{
251 void *oop_ret;
252 oop_source_sys *oop_sys = ev->additional_data;
253
254 oop_ret = oop_sys_run_once(oop_sys);
255 if (oop_ret == OOP_CONTINUE) {
256 return 0;
257 }
258
259 return -1;
260}
261
262/*
263 return on failure or (with 0) if all fd events are removed
264*/
265static int oop_event_loop_wait(struct tevent_context *ev)
266{
267 void *oop_ret;
268 oop_source_sys *oop_sys = ev->additional_data;
269
270 oop_ret = oop_sys_run(oop_sys);
271 if (oop_ret == OOP_CONTINUE) {
272 return 0;
273 }
274
275 return -1;
276}
277
278static 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,
287};
288
289const struct event_ops *event_liboop_get_ops(void)
290{
291 return &event_oop_ops;
292}
Note: See TracBrowser for help on using the repository browser.