2 Unix SMB/CIFS implementation.
4 generalised event loop handling
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Stefan Metzmacher 2005-2009
8 Copyright (C) Volker Lendecke 2008
10 ** NOTE! The following LGPL license applies to the tevent
11 ** library. This does NOT imply that all of Samba is released
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 3 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, see <http://www.gnu.org/licenses/>.
41 #ifdef HAVE_SYS_EPOLL_H
42 #include <sys/epoll.h>
45 #include <atalk/talloc.h>
47 struct tevent_context;
51 struct tevent_immediate;
54 /* event handler types */
55 typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
56 struct tevent_fd *fde,
59 typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev,
60 struct tevent_fd *fde,
63 typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
64 struct tevent_timer *te,
65 struct timeval current_time,
67 typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx,
68 struct tevent_immediate *im,
70 typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
71 struct tevent_signal *se,
77 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
78 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
79 const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
80 void tevent_set_default_backend(const char *backend);
82 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
86 tevent_fd_handler_t handler,
88 const char *handler_name,
89 const char *location);
90 #define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
91 _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
92 #handler, __location__)
94 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
96 struct timeval next_event,
97 tevent_timer_handler_t handler,
99 const char *handler_name,
100 const char *location);
101 #define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \
102 _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
103 #handler, __location__)
105 struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
106 const char *location);
107 #define tevent_create_immediate(mem_ctx) \
108 _tevent_create_immediate(mem_ctx, __location__)
110 void _tevent_schedule_immediate(struct tevent_immediate *im,
111 struct tevent_context *ctx,
112 tevent_immediate_handler_t handler,
114 const char *handler_name,
115 const char *location);
116 #define tevent_schedule_immediate(im, ctx, handler, private_data) \
117 _tevent_schedule_immediate(im, ctx, handler, private_data, \
118 #handler, __location__);
120 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
124 tevent_signal_handler_t handler,
126 const char *handler_name,
127 const char *location);
128 #define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
129 _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
130 #handler, __location__)
132 int _tevent_loop_once(struct tevent_context *ev, const char *location);
133 #define tevent_loop_once(ev) \
134 _tevent_loop_once(ev, __location__) \
136 int _tevent_loop_wait(struct tevent_context *ev, const char *location);
137 #define tevent_loop_wait(ev) \
138 _tevent_loop_wait(ev, __location__) \
140 void tevent_fd_set_close_fn(struct tevent_fd *fde,
141 tevent_fd_close_fn_t close_fn);
142 void tevent_fd_set_auto_close(struct tevent_fd *fde);
143 uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
144 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
146 bool tevent_signal_support(struct tevent_context *ev);
148 void tevent_set_abort_fn(void (*abort_fn)(const char *reason));
150 /* bits for file descriptor event flags */
151 #define TEVENT_FD_READ 1
152 #define TEVENT_FD_WRITE 2
154 #define TEVENT_FD_WRITEABLE(fde) \
155 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE)
156 #define TEVENT_FD_READABLE(fde) \
157 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ)
159 #define TEVENT_FD_NOT_WRITEABLE(fde) \
160 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE)
161 #define TEVENT_FD_NOT_READABLE(fde) \
162 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
165 enum tevent_debug_level {
168 TEVENT_DEBUG_WARNING,
172 int tevent_set_debug(struct tevent_context *ev,
173 void (*debug)(void *context,
174 enum tevent_debug_level level,
176 va_list ap) PRINTF_ATTRIBUTE(3,0),
178 int tevent_set_debug_stderr(struct tevent_context *ev);
181 * An async request moves between the following 4 states:
183 enum tevent_req_state {
185 * we are creating the request
189 * we are waiting the request to complete
191 TEVENT_REQ_IN_PROGRESS,
193 * the request is finished
197 * A user error has occured
199 TEVENT_REQ_USER_ERROR,
203 TEVENT_REQ_TIMED_OUT,
205 * No memory in between
207 TEVENT_REQ_NO_MEMORY,
209 * the request is already received by the caller
215 * @brief An async request
217 * This represents an async request being processed by callbacks via an event
218 * context. A user can issue for example a write request to a socket, giving
219 * an implementation function the fd, the buffer and the number of bytes to
220 * transfer. The function issuing the request will immediately return without
221 * blocking most likely without having sent anything. The API user then fills
222 * in req->async.fn and req->async.private_data, functions that are called
223 * when the request is finished.
225 * It is up to the user of the async request to talloc_free it after it has
226 * finished. This can happen while the completion function is called.
231 typedef void (*tevent_req_fn)(struct tevent_req *);
233 void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt);
234 void *_tevent_req_callback_data(struct tevent_req *req);
235 void *_tevent_req_data(struct tevent_req *req);
237 #define tevent_req_callback_data(_req, _type) \
238 talloc_get_type_abort(_tevent_req_callback_data(_req), _type)
239 #define tevent_req_callback_data_void(_req) \
240 _tevent_req_callback_data(_req)
241 #define tevent_req_data(_req, _type) \
242 talloc_get_type_abort(_tevent_req_data(_req), _type)
244 typedef char *(*tevent_req_print_fn)(struct tevent_req *, TALLOC_CTX *);
246 void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn);
248 char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx);
250 char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req);
252 typedef bool (*tevent_req_cancel_fn)(struct tevent_req *);
254 void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn);
256 bool _tevent_req_cancel(struct tevent_req *req, const char *location);
257 #define tevent_req_cancel(req) \
258 _tevent_req_cancel(req, __location__)
260 struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
264 const char *location);
266 #define tevent_req_create(_mem_ctx, _pstate, _type) \
267 _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \
268 #_type, __location__)
270 bool tevent_req_set_endtime(struct tevent_req *req,
271 struct tevent_context *ev,
272 struct timeval endtime);
274 void _tevent_req_notify_callback(struct tevent_req *req, const char *location);
275 #define tevent_req_notify_callback(req) \
276 _tevent_req_notify_callback(req, __location__)
278 void _tevent_req_done(struct tevent_req *req,
279 const char *location);
280 #define tevent_req_done(req) \
281 _tevent_req_done(req, __location__)
283 bool _tevent_req_error(struct tevent_req *req,
285 const char *location);
286 #define tevent_req_error(req, error) \
287 _tevent_req_error(req, error, __location__)
289 bool _tevent_req_nomem(const void *p,
290 struct tevent_req *req,
291 const char *location);
292 #define tevent_req_nomem(p, req) \
293 _tevent_req_nomem(p, req, __location__)
295 struct tevent_req *tevent_req_post(struct tevent_req *req,
296 struct tevent_context *ev);
298 bool tevent_req_is_in_progress(struct tevent_req *req);
300 bool tevent_req_poll(struct tevent_req *req,
301 struct tevent_context *ev);
303 bool tevent_req_is_error(struct tevent_req *req,
304 enum tevent_req_state *state,
307 void tevent_req_received(struct tevent_req *req);
309 struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx,
310 struct tevent_context *ev,
311 struct timeval wakeup_time);
312 bool tevent_wakeup_recv(struct tevent_req *req);
314 int tevent_timeval_compare(const struct timeval *tv1,
315 const struct timeval *tv2);
317 struct timeval tevent_timeval_zero(void);
319 struct timeval tevent_timeval_current(void);
321 struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs);
323 struct timeval tevent_timeval_until(const struct timeval *tv1,
324 const struct timeval *tv2);
326 bool tevent_timeval_is_zero(const struct timeval *tv);
328 struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs,
331 struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs);
335 struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
337 const char *location);
339 #define tevent_queue_create(_mem_ctx, _name) \
340 _tevent_queue_create((_mem_ctx), (_name), __location__)
342 typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req,
344 bool tevent_queue_add(struct tevent_queue *queue,
345 struct tevent_context *ev,
346 struct tevent_req *req,
347 tevent_queue_trigger_fn_t trigger,
349 void tevent_queue_start(struct tevent_queue *queue);
350 void tevent_queue_stop(struct tevent_queue *queue);
352 size_t tevent_queue_length(struct tevent_queue *queue);
354 typedef int (*tevent_nesting_hook)(struct tevent_context *ev,
359 const char *location);
360 #ifdef TEVENT_DEPRECATED
362 #if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
363 #define _DEPRECATED_ __attribute__ ((deprecated))
368 void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_;
369 void tevent_loop_set_nesting_hook(struct tevent_context *ev,
370 tevent_nesting_hook hook,
371 void *private_data) _DEPRECATED_;
372 int _tevent_loop_until(struct tevent_context *ev,
373 bool (*finished)(void *private_data),
375 const char *location) _DEPRECATED_;
376 #define tevent_loop_until(ev, finished, private_data) \
377 _tevent_loop_until(ev, finished, private_data, __location__)
382 * The following structure and registration functions are exclusively
383 * needed for people writing and pluggin a different event engine.
384 * There is nothing useful for normal tevent user in here.
389 int (*context_init)(struct tevent_context *ev);
391 /* fd_event functions */
392 struct tevent_fd *(*add_fd)(struct tevent_context *ev,
394 int fd, uint16_t flags,
395 tevent_fd_handler_t handler,
397 const char *handler_name,
398 const char *location);
399 void (*set_fd_close_fn)(struct tevent_fd *fde,
400 tevent_fd_close_fn_t close_fn);
401 uint16_t (*get_fd_flags)(struct tevent_fd *fde);
402 void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags);
404 /* timed_event functions */
405 struct tevent_timer *(*add_timer)(struct tevent_context *ev,
407 struct timeval next_event,
408 tevent_timer_handler_t handler,
410 const char *handler_name,
411 const char *location);
413 /* immediate event functions */
414 void (*schedule_immediate)(struct tevent_immediate *im,
415 struct tevent_context *ev,
416 tevent_immediate_handler_t handler,
418 const char *handler_name,
419 const char *location);
421 /* signal functions */
422 struct tevent_signal *(*add_signal)(struct tevent_context *ev,
424 int signum, int sa_flags,
425 tevent_signal_handler_t handler,
427 const char *handler_name,
428 const char *location);
431 int (*loop_once)(struct tevent_context *ev, const char *location);
432 int (*loop_wait)(struct tevent_context *ev, const char *location);
435 bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
439 * The following definitions are usueful only for compatibility with the
440 * implementation originally developed within the samba4 code and will be
441 * soon removed. Please NEVER use in new code.
444 #ifdef TEVENT_COMPAT_DEFINES
446 #define event_context tevent_context
447 #define event_ops tevent_ops
448 #define fd_event tevent_fd
449 #define timed_event tevent_timer
450 #define signal_event tevent_signal
452 #define event_fd_handler_t tevent_fd_handler_t
453 #define event_timed_handler_t tevent_timer_handler_t
454 #define event_signal_handler_t tevent_signal_handler_t
456 #define event_context_init(mem_ctx) \
457 tevent_context_init(mem_ctx)
459 #define event_context_init_byname(mem_ctx, name) \
460 tevent_context_init_byname(mem_ctx, name)
462 #define event_backend_list(mem_ctx) \
463 tevent_backend_list(mem_ctx)
465 #define event_set_default_backend(backend) \
466 tevent_set_default_backend(backend)
468 #define event_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
469 tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data)
471 #define event_add_timed(ev, mem_ctx, next_event, handler, private_data) \
472 tevent_add_timer(ev, mem_ctx, next_event, handler, private_data)
474 #define event_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
475 tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data)
477 #define event_loop_once(ev) \
480 #define event_loop_wait(ev) \
483 #define event_get_fd_flags(fde) \
484 tevent_fd_get_flags(fde)
486 #define event_set_fd_flags(fde, flags) \
487 tevent_fd_set_flags(fde, flags)
489 #define EVENT_FD_READ TEVENT_FD_READ
490 #define EVENT_FD_WRITE TEVENT_FD_WRITE
492 #define EVENT_FD_WRITEABLE(fde) \
493 TEVENT_FD_WRITEABLE(fde)
495 #define EVENT_FD_READABLE(fde) \
496 TEVENT_FD_READABLE(fde)
498 #define EVENT_FD_NOT_WRITEABLE(fde) \
499 TEVENT_FD_NOT_WRITEABLE(fde)
501 #define EVENT_FD_NOT_READABLE(fde) \
502 TEVENT_FD_NOT_READABLE(fde)
504 #define ev_debug_level tevent_debug_level
506 #define EV_DEBUG_FATAL TEVENT_DEBUG_FATAL
507 #define EV_DEBUG_ERROR TEVENT_DEBUG_ERROR
508 #define EV_DEBUG_WARNING TEVENT_DEBUG_WARNING
509 #define EV_DEBUG_TRACE TEVENT_DEBUG_TRACE
511 #define ev_set_debug(ev, debug, context) \
512 tevent_set_debug(ev, debug, context)
514 #define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev)
516 #endif /* TEVENT_COMPAT_DEFINES */
518 #endif /* __TEVENT_H__ */