138 lines
3.6 KiB
Plaintext
138 lines
3.6 KiB
Plaintext
|
|
/**
|
|||
|
|
@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 10 since it came from foo_send
|
|||
|
|
struct foo_state *a = tevent_req_data(req, struct foo_state);
|
|||
|
|
|
|||
|
|
// b->y contains 9 since it came from run
|
|||
|
|
struct testA *b = tevent_req_callback_data(req, struct testA);
|
|||
|
|
|
|||
|
|
// c->y contains 9 since it came from run we just used a different way
|
|||
|
|
// of getting it.
|
|||
|
|
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);
|
|||
|
|
|
|||
|
|
// Note that we did not use the private data passed in
|
|||
|
|
|
|||
|
|
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 = 11;
|
|||
|
|
|
|||
|
|
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: 10
|
|||
|
|
b->y: 9
|
|||
|
|
c->y: 9
|
|||
|
|
@endcode
|
|||
|
|
|
|||
|
|
*/
|