208 lines
5.3 KiB
C
208 lines
5.3 KiB
C
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <tevent.h>
|
|
#include <sys/time.h>
|
|
#include <signal.h>
|
|
#include <assert.h>
|
|
#include <pthread.h>
|
|
|
|
struct state {
|
|
struct timeval endtime;
|
|
int counter;
|
|
TALLOC_CTX *ctx;
|
|
};
|
|
|
|
struct info_struct {
|
|
int counter;
|
|
};
|
|
|
|
static void callback(struct tevent_context *ev, struct tevent_timer *tim,
|
|
struct timeval current_time, void *private_data) {
|
|
struct state *data = talloc_get_type_abort(private_data, struct state);
|
|
struct tevent_timer *time_event;
|
|
struct timeval schedule;
|
|
|
|
data->counter += 1;
|
|
|
|
if (tevent_timeval_compare(¤t_time, &(data->endtime)) < 0) {
|
|
|
|
schedule = tevent_timeval_current_ofs(1, 0);
|
|
time_event = tevent_add_timer(ev, data->ctx, schedule, callback, data);
|
|
assert(time_event);
|
|
}
|
|
}
|
|
|
|
int test_tevent_timer(void) {
|
|
struct tevent_context *event_ctx;
|
|
struct tevent_timer *time_event;
|
|
struct timeval schedule;
|
|
struct state *data;
|
|
TALLOC_CTX *mem_ctx;
|
|
|
|
assert((mem_ctx = talloc_new(NULL)));
|
|
assert((event_ctx = tevent_context_init(mem_ctx)));
|
|
|
|
assert((data = talloc(mem_ctx, struct state)));
|
|
|
|
schedule = tevent_timeval_current_ofs(1, 0);
|
|
data->endtime = tevent_timeval_add(&schedule, 2, 0);
|
|
data->ctx = mem_ctx;
|
|
data->counter = 0;
|
|
|
|
time_event = tevent_add_timer(event_ctx, mem_ctx, schedule, callback, data);
|
|
tevent_loop_wait(event_ctx);
|
|
|
|
assert(data->counter == 3);
|
|
talloc_free(mem_ctx);
|
|
}
|
|
|
|
static void foo(struct tevent_context *ev, struct tevent_immediate *im, void *private_data) {
|
|
struct info_struct *data = talloc_get_type_abort(private_data, struct info_struct);
|
|
|
|
data->counter++;
|
|
}
|
|
|
|
int test_tevent_immediate(void) {
|
|
struct tevent_context *event_ctx;
|
|
struct tevent_immediate *im;
|
|
struct info_struct *data;
|
|
TALLOC_CTX *mem_ctx;
|
|
|
|
assert((mem_ctx = talloc_new(NULL)));
|
|
|
|
event_ctx = tevent_context_init(mem_ctx);
|
|
|
|
assert((data = talloc(mem_ctx, struct info_struct)));
|
|
data->counter = 0;
|
|
|
|
assert((im = tevent_create_immediate(mem_ctx)));
|
|
|
|
tevent_schedule_immediate(im, event_ctx, foo, data);
|
|
tevent_loop_wait(event_ctx);
|
|
|
|
assert(data->counter == 1);
|
|
|
|
talloc_free(mem_ctx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int signal_data;
|
|
|
|
static void handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) {
|
|
signal_data = 1;
|
|
}
|
|
|
|
int test_tevent_signal(void) {
|
|
struct tevent_context *event_ctx;
|
|
struct tevent_signal *sig;
|
|
TALLOC_CTX *mem_ctx;
|
|
|
|
mem_ctx = talloc_new(NULL);
|
|
assert(mem_ctx);
|
|
|
|
event_ctx = tevent_context_init(mem_ctx);
|
|
assert(event_ctx);
|
|
|
|
if (tevent_signal_support(event_ctx)) {
|
|
sig = tevent_add_signal(event_ctx, mem_ctx, SIGINT, 0, handler, NULL);
|
|
assert(sig);
|
|
tevent_loop_once(event_ctx);
|
|
}
|
|
|
|
talloc_free(mem_ctx);
|
|
}
|
|
|
|
struct foo_state {
|
|
int x;
|
|
};
|
|
|
|
struct testA {
|
|
int y;
|
|
};
|
|
|
|
static void foo_done(struct tevent_req *req) {
|
|
struct foo_state *a = tevent_req_data(req, struct foo_state);
|
|
struct testA *b = tevent_req_callback_data(req, struct testA);
|
|
struct testA *c = (struct testA *) tevent_req_callback_data_void(req);
|
|
|
|
assert(a->x == 10);
|
|
assert(b->y == 9);
|
|
assert(c->y == 9);
|
|
|
|
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) {
|
|
struct tevent_req *req;
|
|
struct foo_state *state;
|
|
|
|
printf("_send\n");
|
|
|
|
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 test_event_data(void) {
|
|
struct tevent_context *event_ctx;
|
|
struct tevent_timer *time_event;
|
|
struct testA *data;
|
|
TALLOC_CTX *mem_ctx;
|
|
|
|
mem_ctx = talloc_new(NULL);
|
|
assert(mem_ctx);
|
|
|
|
event_ctx = tevent_context_init(mem_ctx);
|
|
assert(event_ctx);
|
|
|
|
data = talloc(mem_ctx, struct testA);
|
|
data->y = 11;
|
|
time_event = tevent_add_timer(event_ctx,
|
|
mem_ctx,
|
|
tevent_timeval_current(),
|
|
run,
|
|
data);
|
|
assert(time_event);
|
|
|
|
tevent_loop_once(event_ctx);
|
|
talloc_free(mem_ctx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main() {
|
|
pid_t pid, ppid;
|
|
int r;
|
|
|
|
test_tevent_timer();
|
|
test_tevent_immediate();
|
|
|
|
/* signal test */
|
|
ppid = getpid();
|
|
if((pid = fork()) == 0) {
|
|
sleep(1);
|
|
kill(ppid, SIGINT);
|
|
exit(0);
|
|
} else {
|
|
test_tevent_signal();
|
|
}
|
|
assert(signal_data == 1);
|
|
|
|
test_event_data();
|
|
}
|