2 @page tevent_events Chapter 2: Tevent events
3 @section pools Tevent events
5 Ok, after reading previous chapter we can start doing something useful. So, the
6 way of creating events is similar for all types - signals, file descriptors,
7 time or immediate events. At the beginning it is good to know about some
8 typedefs which are set in tevent library and which specify the arguments for
9 each callback. These callbacks are:
11 - tevent_timer_handler_t()
13 - tevent_immediate_handler_t()
15 - tevent_signal_handler_t()
17 - tevent_fd_handler_t()
19 According their names it is obvious that for creating callback for e.g. time
20 event, tevent_timer_handler_t will be used.
22 The best way how to introduce registering an event and setting up a callback
23 would be example, so examples describing all the types of events follow.
25 @subsection Time Time event
27 This example shows how to set up an event which will be repeated for a minute
28 with interval of 2 seconds (will be triggered 30 times). After exceeding this
29 limit, the event loop will finish and all the memory resources will be freed.
30 This is just example describing repeated activity, nothing usefull is done
40 struct timeval endtime;
45 static void callback(struct tevent_context *ev, struct tevent_timer *tim,
46 struct timeval current_time, void *private_data)
48 struct state *data = talloc_get_type_abort(private_data, struct state);
49 struct tevent_timer *time_event;
50 struct timeval schedule;
52 printf("Data value: %d\n", data->counter);
53 data->counter += 1; // increase counter
55 // if time has not reached its limit, set another event
56 if (tevent_timeval_compare(¤t_time, &(data->endtime)) < 0) {
58 // set repeat with delay 2 seconds
59 schedule = tevent_timeval_current_ofs(2, 0);
60 time_event = tevent_add_timer(ev, data->ctx, schedule, callback, data);
61 if (time_event == NULL) { // error ...
62 fprintf(stderr, "MEMORY PROBLEM\n");
66 // time limit exceeded
71 struct tevent_context *event_ctx;
73 struct tevent_timer *time_event;
74 struct timeval schedule;
76 mem_ctx = talloc_new(NULL); // parent
77 event_ctx = tevent_context_init(mem_ctx);
79 struct state *data = talloc(mem_ctx, struct state);
81 schedule = tevent_timeval_current_ofs(2, 0); // +2 second time value
82 data->endtime = tevent_timeval_add(&schedule, 60, 0); // one minute time limit
87 time_event = tevent_add_timer(event_ctx, mem_ctx, schedule, callback, data);
88 if (time_event == NULL) {
89 fprintf(stderr, "FAILED\n");
93 tevent_loop_wait(event_ctx);
99 Variable <code>counter</code> is only used for counting the number of triggered
100 functions. List of all available functions which tevent offers for working with
102 <a href="http://tevent.samba.org/group__tevent__helpers.html">here</a> together
103 with their description. More detailed view at these functions is unnecessary
104 because their purpose and usage is quite simple and clear.
106 @subsection Immediate Immediate event
108 These events are, as their name indicates, activated and performed immediately.
109 It means that this kind of events have priority over others (except signal
110 events). So if there is a bulk of events registered and after that a
111 tevent loop is launched, then all the immediate events will be triggered before
112 the other events. Except other immediate events (and signal events) because
113 they are also processed sequentially - according the order they were scheduled.
114 Signals have the highest priority and therefore they are processed
115 preferentially. Therefore the expression immediate may not correspond exactly
116 to the dictionary definition of "something without delay" but rather "as soon
117 as possible" after all preceding immediate events.
119 For creating an immediate event there is a small different which lies in the
120 fact that the creation of such event is done in 2 steps. One represents the
121 creation (memory allocation), the second one represents registering as the
122 event within some tevent context.
125 struct tevent_immediate *run(TALLOC_CTX* mem_ctx,
126 struct tevent_context event_ctx,
129 struct tevent_immediate *im;
131 im = tevent_create_immediate(mem_ctx);
135 tevent_schedule_immediate(im, event_ctx, foo, data);
141 Example which may be compiled and run representing the creation of immediate event.
153 static void foo(struct tevent_context *ev, struct tevent_immediate *im,
156 struct info_struct *data = talloc_get_type_abort(private_data, struct info_struct);
157 printf("Data value: %d\n", data->counter);
161 struct tevent_context *event_ctx;
163 struct tevent_immediate *im;
167 mem_ctx = talloc_new(NULL);
168 event_ctx = tevent_context_init(mem_ctx);
170 struct info_struct *data = talloc(mem_ctx, struct info_struct);
172 // setting up private data
175 // first immediate event
176 im = tevent_create_immediate(mem_ctx);
178 fprintf(stderr, "FAILED\n");
181 tevent_schedule_immediate(im, event_ctx, foo, data);
183 tevent_loop_wait(event_ctx);
184 talloc_free(mem_ctx);
190 @subsection Signal Signal event
192 This is an alternative to standard C library functions signal() or sigaction().
193 The main difference that distinguishes these ways of treating signals is their
194 setting up of handlers for different time intervals of the running program.
196 While standard C library methods for dealing with signals offer sufficient
197 tools for most cases, they are inadequate for handling signals within the
198 tevent loop. It could be necessary to finish certain tevent requests within the
199 tevent loop without interruption. If a signal was sent to a program at a moment
200 when the tevent loop is in progress, a standard signal handler would not return
201 processing to the application at the very same place and it would quit the
202 tevent loop for ever. In such cases, tevent signal handlers offer the
203 possibility of dealing with these signals by masking them from the rest of
204 application and not quitting the loop, so the other events can still be
207 Tevent offers also a control function, which enables us to verify whether it is
208 possible to handle signals via tevent, is defined within tevent library and it
209 returns a boolean value revealing the result of the verification.
212 bool tevent_signal_support (struct tevent_context *ev)
215 Checking for signal support is not necessary, but if it is not guaranteed, this
216 is a good and easy control to prevent unexpected behaviour or failure of the
217 program occurring. Such a test of course does not have to be run every single
218 time you wish to create a signal handler, but simply at the beginning - during
219 the initialization procedures of the program. Afterthat, simply adapt to each
220 situation that arises.
228 static void handler(struct tevent_context *ev,
229 struct tevent_signal *se,
236 // Do something usefull
238 printf("handling signal...\n");
244 struct tevent_context *event_ctx;
246 struct tevent_signal *sig;
248 mem_ctx = talloc_new(NULL); //parent
249 if (mem_ctx == NULL) {
250 fprintf(stderr, "FAILED\n");
254 event_ctx = tevent_context_init(mem_ctx);
255 if (event_ctx == NULL) {
256 fprintf(stderr, "FAILED\n");
260 if (tevent_signal_support(event_ctx)) {
261 // create signal event
262 sig = tevent_add_signal(event_ctx, mem_ctx, SIGINT, 0, handler, NULL);
264 fprintf(stderr, "FAILED\n");
267 tevent_loop_wait(event_ctx);
270 talloc_free(mem_ctx);
276 @subsection File File descriptor event
278 Support of events on file descriptors is mainly useful for socket communication
279 but it certainly works flawlessly with standard streams (stdin, stdout, stderr)
280 as well. Working asynchronously with file descriptors enables switching
281 within processing I/O operations. This ability may rise with a greater
282 number of I/O operations and such overlapping leads to enhancement of the
285 There are several other functions included in tevent API related to handling
286 file descriptors (there are too many functions defined within tevent therefore
287 just some of them are fully described within this thesis. The
288 declaration of the rest can be easily found on the library’s website or
289 directly from the source code):
292 <li>tevent_fd_set_close_fn() - can add another function to be called at the
293 moment when a structure tevent fd is freed.</li>
294 <li>tevent_fd_set_auto_close() - calling this function can simplify the
295 maintenance of file descriptors, because it instructs tevent to close the
296 appropriate file descriptor when the tevent fd structure is about to be
298 <li>tevent_fd_get_flags() - returns flags which are set on the file descriptor
299 connected with this tevent fd structure.</li>
300 <li>tevent_fd_set_flags() - sets specified flags on the event’s file
306 static void close_fd(struct tevent_context *ev, struct tevent_fd *fd_event,
307 int fd, void *private_data)
309 // processing when fd_event is freed
312 struct static void handler(struct tevent_context *ev,
313 struct tevent_fd *fde,
317 // handling event; reading from a file descriptor
318 tevent_fd_set_close_fn (fd_event, close_fd);
321 int run(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx,
322 int fd, uint16_t flags, char *buffer)
324 struct tevent_fd* fd_event = NULL;
326 if (flags & TEVENT_FD_READ) {
327 fd_event = tevent_add_fd(event_ctx,
334 if (fd_event == NULL) {
337 return tevent_loop_once();