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
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/>.
27 #include "events_internal.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
);
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
;
57 oop_sys
= oop_sys_new();
62 talloc_set_destructor(ev
, oop_event_context_destructor
);
65 ev
->additional_data
= oop_sys
;
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
;
78 fde
->handler(fde
->event_ctx
, fde
, EVENT_FD_READ
, fde
->private_data
);
81 fde
->handler(fde
->event_ctx
, fde
, EVENT_FD_WRITE
, fde
->private_data
);
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
) {
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
,
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
;
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
);
149 return the fd event flags
151 static uint16_t oop_event_get_fd_flags(struct tevent_fd
*fde
)
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
;
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
);
182 static int oop_event_timed_destructor(struct tevent_timer
*te
);
184 static int oop_event_timed_deny_destructor(struct tevent_timer
*te
)
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
);
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
);
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
,
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
;
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
);
247 do a single event loop using the events defined in ev
249 static int oop_event_loop_once(struct tevent_context
*ev
)
252 oop_source_sys
*oop_sys
= ev
->additional_data
;
254 oop_ret
= oop_sys_run_once(oop_sys
);
255 if (oop_ret
== OOP_CONTINUE
) {
263 return on failure or (with 0) if all fd events are removed
265 static int oop_event_loop_wait(struct tevent_context
*ev
)
268 oop_source_sys
*oop_sys
= ev
->additional_data
;
270 oop_ret
= oop_sys_run(oop_sys
);
271 if (oop_ret
== OOP_CONTINUE
) {
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
;