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