d3e1ecb4f1134953984b3183a30d1cb6f85e74d0
[ira/wip.git] / lib / tevent / tevent.h
1 /* 
2    Unix SMB/CIFS implementation.
3
4    generalised event loop handling
5
6    Copyright (C) Andrew Tridgell 2005
7    Copyright (C) Stefan Metzmacher 2005-2009
8    Copyright (C) Volker Lendecke 2008
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #ifndef __TEVENT_H__
25 #define __TEVENT_H__
26
27 #include <stdint.h>
28 #include <talloc.h>
29 #include <sys/time.h>
30
31 struct tevent_context;
32 struct tevent_ops;
33 struct tevent_fd;
34 struct tevent_timer;
35 struct tevent_signal;
36
37 /* event handler types */
38 typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
39                                     struct tevent_fd *fde,
40                                     uint16_t flags,
41                                     void *private_data);
42 typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev,
43                                      struct tevent_fd *fde,
44                                      int fd,
45                                      void *private_data);
46 typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
47                                        struct tevent_timer *te,
48                                        struct timeval current_time,
49                                        void *private_data);
50 typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
51                                         struct tevent_signal *se,
52                                         int signum,
53                                         int count,
54                                         void *siginfo,
55                                         void *private_data);
56
57 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
58 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
59 const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
60 void tevent_set_default_backend(const char *backend);
61
62 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
63                                  TALLOC_CTX *mem_ctx,
64                                  int fd,
65                                  uint16_t flags,
66                                  tevent_fd_handler_t handler,
67                                  void *private_data,
68                                  const char *handler_name,
69                                  const char *location);
70 #define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
71         _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
72                        #handler, __location__)
73
74 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
75                                        TALLOC_CTX *mem_ctx,
76                                        struct timeval next_event,
77                                        tevent_timer_handler_t handler,
78                                        void *private_data,
79                                        const char *handler_name,
80                                        const char *location);
81 #define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \
82         _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
83                           #handler, __location__)
84
85 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
86                                          TALLOC_CTX *mem_ctx,
87                                          int signum,
88                                          int sa_flags,
89                                          tevent_signal_handler_t handler,
90                                          void *private_data,
91                                          const char *handler_name,
92                                          const char *location);
93 #define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
94         _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
95                            #handler, __location__)
96
97 int tevent_loop_once(struct tevent_context *ev);
98 int tevent_loop_wait(struct tevent_context *ev);
99
100 void tevent_fd_set_close_fn(struct tevent_fd *fde,
101                             tevent_fd_close_fn_t close_fn);
102 void tevent_fd_set_auto_close(struct tevent_fd *fde);
103 uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
104 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
105
106 /* bits for file descriptor event flags */
107 #define TEVENT_FD_READ 1
108 #define TEVENT_FD_WRITE 2
109
110 #define TEVENT_FD_WRITEABLE(fde) \
111         tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE)
112 #define TEVENT_FD_READABLE(fde) \
113         tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ)
114
115 #define TEVENT_FD_NOT_WRITEABLE(fde) \
116         tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE)
117 #define TEVENT_FD_NOT_READABLE(fde) \
118         tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
119
120 /* DEBUG */
121 enum tevent_debug_level {
122         TEVENT_DEBUG_FATAL,
123         TEVENT_DEBUG_ERROR,
124         TEVENT_DEBUG_WARNING,
125         TEVENT_DEBUG_TRACE
126 };
127
128 int tevent_set_debug(struct tevent_context *ev,
129                      void (*debug)(void *context,
130                                    enum tevent_debug_level level,
131                                    const char *fmt,
132                                    va_list ap) PRINTF_ATTRIBUTE(3,0),
133                      void *context);
134 int tevent_set_debug_stderr(struct tevent_context *ev);
135
136 /**
137  * An async request moves between the following 4 states:
138  */
139 enum tevent_req_state {
140         /**
141          * we are creating the request
142          */
143         TEVENT_REQ_INIT,
144         /**
145          * we are waiting the request to complete
146          */
147         TEVENT_REQ_IN_PROGRESS,
148         /**
149          * the request is finished
150          */
151         TEVENT_REQ_DONE,
152         /**
153          * A user error has occured
154          */
155         TEVENT_REQ_USER_ERROR,
156         /**
157          * Request timed out
158          */
159         TEVENT_REQ_TIMED_OUT,
160         /**
161          * No memory in between
162          */
163         TEVENT_REQ_NO_MEMORY
164 };
165
166 /**
167  * @brief An async request
168  *
169  * This represents an async request being processed by callbacks via an event
170  * context. A user can issue for example a write request to a socket, giving
171  * an implementation function the fd, the buffer and the number of bytes to
172  * transfer. The function issuing the request will immediately return without
173  * blocking most likely without having sent anything. The API user then fills
174  * in req->async.fn and req->async.private_data, functions that are called
175  * when the request is finished.
176  *
177  * It is up to the user of the async request to talloc_free it after it has
178  * finished. This can happen while the completion function is called.
179  */
180
181 struct tevent_req {
182         /**
183          * @brief What to do on completion
184          *
185          * This is used for the user of an async request, fn is called when
186          * the request completes, either successfully or with an error.
187          */
188         struct {
189                 /**
190                  * @brief Completion function
191                  * Completion function, to be filled by the API user
192                  */
193                 void (*fn)(struct tevent_req *);
194                 /**
195                  * @brief Private data for the completion function
196                  */
197                 void *private_data;
198         } async;
199
200         /**
201          * @brief Private state pointer for the actual implementation
202          *
203          * The implementation doing the work for the async request needs a
204          * current state like for example a fd event. The user of an async
205          * request should not touch this.
206          */
207         void *private_state;
208
209         /**
210          * @brief Internal state of the request
211          *
212          * Callers should only access this via functions and never directly.
213          */
214         struct {
215                 /**
216                  * @brief The talloc type of the private_state pointer
217                  *
218                  * This is filled by the tevent_req_create() macro.
219                  *
220                  * This for debugging only.
221                  */
222                 const char *private_type;
223
224                 /**
225                  * @brief The location where the request was created
226                  *
227                  * This uses the __location__ macro via the tevent_req_create()
228                  * macro.
229                  *
230                  * This for debugging only.
231                  */
232                 const char *location;
233
234                 /**
235                  * @brief The external state - will be queried by the caller
236                  *
237                  * While the async request is being processed, state will remain in
238                  * TEVENT_REQ_IN_PROGRESS. A request is finished if
239                  * req->state>=TEVENT_REQ_DONE.
240                  */
241                 enum tevent_req_state state;
242
243                 /**
244                  * @brief status code when finished
245                  *
246                  * This status can be queried in the async completion function. It
247                  * will be set to 0 when everything went fine.
248                  */
249                 uint64_t error;
250
251                 /**
252                  * @brief the timer event if tevent_req_post was used
253                  *
254                  */
255                 struct tevent_timer *trigger;
256
257                 /**
258                  * @brief the timer event if tevent_req_set_timeout was used
259                  *
260                  */
261                 struct tevent_timer *timer;
262         } internal;
263 };
264
265 char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req);
266
267 struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
268                                       void *pstate,
269                                       size_t state_size,
270                                       const char *type,
271                                       const char *location);
272
273 #define tevent_req_create(_mem_ctx, _pstate, _type) \
274         _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \
275                            #_type, __location__)
276
277 bool tevent_req_set_timeout(struct tevent_req *req,
278                             struct tevent_context *ev,
279                             struct timeval endtime);
280
281 void tevent_req_done(struct tevent_req *req);
282
283 bool tevent_req_error(struct tevent_req *req,
284                       uint64_t error);
285
286 bool tevent_req_nomem(const void *p,
287                       struct tevent_req *req);
288
289 struct tevent_req *tevent_req_post(struct tevent_req *req,
290                                    struct tevent_context *ev);
291
292 bool tevent_req_is_in_progress(struct tevent_req *req);
293
294 bool tevent_req_is_error(struct tevent_req *req,
295                          enum tevent_req_state *state,
296                          uint64_t *error);
297
298
299 #ifdef TEVENT_COMPAT_DEFINES
300
301 #define event_context   tevent_context
302 #define event_ops       tevent_ops
303 #define fd_event        tevent_fd
304 #define timed_event     tevent_timer
305 #define signal_event    tevent_signal
306
307 #define event_fd_handler_t      tevent_fd_handler_t
308 #define event_timed_handler_t   tevent_timer_handler_t
309 #define event_signal_handler_t  tevent_signal_handler_t
310
311 #define event_context_init(mem_ctx) \
312         tevent_context_init(mem_ctx)
313
314 #define event_context_init_byname(mem_ctx, name) \
315         tevent_context_init_byname(mem_ctx, name)
316
317 #define event_backend_list(mem_ctx) \
318         tevent_backend_list(mem_ctx)
319
320 #define event_set_default_backend(backend) \
321         tevent_set_default_backend(backend)
322
323 #define event_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
324         tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data)
325
326 #define event_add_timed(ev, mem_ctx, next_event, handler, private_data) \
327         tevent_add_timer(ev, mem_ctx, next_event, handler, private_data)
328
329 #define event_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
330         tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data)
331
332 #define event_loop_once(ev) \
333         tevent_loop_once(ev)
334
335 #define event_loop_wait(ev) \
336         tevent_loop_wait(ev)
337
338 #define event_get_fd_flags(fde) \
339         tevent_fd_get_flags(fde)
340
341 #define event_set_fd_flags(fde, flags) \
342         tevent_fd_set_flags(fde, flags)
343
344 #define EVENT_FD_READ           TEVENT_FD_READ
345 #define EVENT_FD_WRITE          TEVENT_FD_WRITE
346
347 #define EVENT_FD_WRITEABLE(fde) \
348         TEVENT_FD_WRITEABLE(fde)
349
350 #define EVENT_FD_READABLE(fde) \
351         TEVENT_FD_READABLE(fde)
352
353 #define EVENT_FD_NOT_WRITEABLE(fde) \
354         TEVENT_FD_NOT_WRITEABLE(fde)
355
356 #define EVENT_FD_NOT_READABLE(fde) \
357         TEVENT_FD_NOT_READABLE(fde)
358
359 #define ev_debug_level          tevent_debug_level
360
361 #define EV_DEBUG_FATAL          TEVENT_DEBUG_FATAL
362 #define EV_DEBUG_ERROR          TEVENT_DEBUG_ERROR
363 #define EV_DEBUG_WARNING        TEVENT_DEBUG_WARNING
364 #define EV_DEBUG_TRACE          TEVENT_DEBUG_TRACE
365
366 #define ev_set_debug(ev, debug, context) \
367         tevent_set_debug(ev, debug, context)
368
369 #define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev)
370
371 #endif /* TEVENT_COMPAT_DEFINES */
372
373 #endif /* __TEVENT_H__ */