1tevent_data(3) tevent tevent_data(3)
2
3
4
6 tevent_data - Chapter 3: Accessing data
7
8
10 A tevent request is (usually) created together with a structure for
11 storing the data necessary for an asynchronous computation. For these
12 private data, tevent library uses void (generic) pointers, therefore
13 any data type can be very simply pointed at. However, this attitude
14 requires clear and guaranteed knowledge of the data type that will be
15 handled, in advance. Private data can be of 2 types: connected with a
16 request itself or given as an individual argument to a callback. It is
17 necessary to differentiate these types, because there is a slightly
18 different method of data access for each. There are two possibilities
19 how to access data that is given as an argument directly to a callback.
20 The difference lies in the pointer that is returned. In one case it is
21 the data type specified in the function’s argument, in another void* is
22 returned.
23
24 void tevent_req_callback_data (struct tevent_req *req, #type)
25 void tevent_req_callback_data_void (struct tevent_req *req)
26
27 To obtain data that are strictly bound to a request, this function is
28 the only direct procedure.
29
30 void *tevent_req_data (struct tevent_req *req, #type)
31
32 Example with both calls which differs between private data within
33 tevent request and data handed over as an argument.
34
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <tevent.h>
38
39 struct foo_state {
40 int x;
41 };
42
43 struct testA {
44 int y;
45 };
46
47
48 static void foo_done(struct tevent_req *req) {
49 // a->x contains 10 since it came from foo_send
50 struct foo_state *a = tevent_req_data(req, struct foo_state);
51
52 // b->y contains 9 since it came from run
53 struct testA *b = tevent_req_callback_data(req, struct testA);
54
55 // c->y contains 9 since it came from run we just used a different way
56 // of getting it.
57 struct testA *c = (struct testA *)tevent_req_callback_data_void(req);
58
59 printf("a->x: %d0, a->x);
60 printf("b->y: %d0, b->y);
61 printf("c->y: %d0, c->y);
62 }
63
64
65 struct tevent_req * foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx) {
66
67 printf("_send0);
68 struct tevent_req *req;
69 struct foo_state *state;
70
71 req = tevent_req_create(event_ctx, &state, struct foo_state);
72 state->x = 10;
73
74 return req;
75 }
76
77 static void run(struct tevent_context *ev, struct tevent_timer *te,
78 struct timeval current_time, void *private_data) {
79 struct tevent_req *req;
80 struct testA *tmp = talloc(ev, struct testA);
81
82 // Note that we did not use the private data passed in
83
84 tmp->y = 9;
85 req = foo_send(ev, ev);
86
87 tevent_req_set_callback(req, foo_done, tmp);
88 tevent_req_done(req);
89
90 }
91
92 int main (int argc, char **argv) {
93
94 struct tevent_context *event_ctx;
95 struct testA *data;
96 TALLOC_CTX *mem_ctx;
97 struct tevent_timer *time_event;
98
99 mem_ctx = talloc_new(NULL); //parent
100 if (mem_ctx == NULL)
101 return EXIT_FAILURE;
102
103 event_ctx = tevent_context_init(mem_ctx);
104 if (event_ctx == NULL)
105 return EXIT_FAILURE;
106
107 data = talloc(mem_ctx, struct testA);
108 data->y = 11;
109
110 time_event = tevent_add_timer(event_ctx,
111 mem_ctx,
112 tevent_timeval_current(),
113 run,
114 data);
115 if (time_event == NULL) {
116 fprintf(stderr, " FAILED0);
117 return EXIT_FAILURE;
118 }
119
120 tevent_loop_once(event_ctx);
121
122 talloc_free(mem_ctx);
123
124 printf("Quit0);
125 return EXIT_SUCCESS;
126 }
127
128 Output of this example is:
129
130 a->x: 10
131 b->y: 9
132 c->y: 9
133
134Version 0.9.8 Wed Sep 11 2019 tevent_data(3)