1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

tevent: add a test that frees wrapper_ev with pending events

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Ralph Boehme
2018-06-16 16:55:44 +02:00
parent 4991c935c0
commit 6189446abe

View File

@ -1048,6 +1048,159 @@ pop_use:
goto done;
}
static void test_free_wrapper_signal_handler(struct tevent_context *ev,
struct tevent_signal *se,
int signum,
int count,
void *siginfo,
void *private_data)
{
struct torture_context *tctx =
talloc_get_type_abort(private_data,
struct torture_context);
torture_comment(tctx, "signal handler\n");
talloc_free(se);
/*
* signal handlers have highest priority in tevent, so this signal
* handler will always be started before the other handlers
* below. Freeing the (wrapper) event context here tests that the
* wrapper implementation correclty handles the wrapper ev going away
* with pending events.
*/
talloc_free(ev);
return;
}
static void test_free_wrapper_fd_handler(struct tevent_context *ev,
struct tevent_fd *fde,
unsigned short fd_flags,
void *private_data)
{
/*
* This should never be called as
* test_free_wrapper_signal_handler()
* already destroyed the wrapper tevent_context.
*/
abort();
}
static void test_free_wrapper_immediate_handler(struct tevent_context *ev,
struct tevent_immediate *im,
void *private_data)
{
/*
* This should never be called as
* test_free_wrapper_signal_handler()
* already destroyed the wrapper tevent_context.
*/
abort();
}
static void test_free_wrapper_timer_handler(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval tv,
void *private_data)
{
/*
* This should never be called as
* test_free_wrapper_signal_handler()
* already destroyed the wrapper tevent_context.
*/
abort();
}
static bool test_free_wrapper(struct torture_context *tctx,
const void *test_data)
{
struct test_wrapper_state *state = NULL;
int sock[2] = { -1, -1};
uint8_t c = 0;
const char *backend = (const char *)test_data;
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_context *ev = NULL;
struct tevent_context *wrap_ev = NULL;
struct tevent_fd *fde = NULL;
struct tevent_timer *te = NULL;
struct tevent_signal *se = NULL;
struct tevent_immediate *im = NULL;
int ret;
bool ok = false;
ev = tevent_context_init_byname(frame, backend);
if (ev == NULL) {
torture_skip(tctx, talloc_asprintf(tctx,
"event backend '%s' not supported\n",
backend));
return true;
}
tevent_set_debug_stderr(ev);
torture_comment(tctx, "tevent backend '%s'\n", backend);
wrap_ev = tevent_context_wrapper_create(
ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state);
torture_assert_not_null_goto(tctx, wrap_ev, ok, done,
"tevent_context_wrapper_create failed\n");
*state = (struct test_wrapper_state) {
.tctx = tctx,
};
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n");
fde = tevent_add_fd(wrap_ev, frame,
sock[1],
TEVENT_FD_READ,
test_free_wrapper_fd_handler,
NULL);
torture_assert_not_null_goto(tctx, fde, ok, done,
"tevent_add_fd failed\n");
te = tevent_add_timer(wrap_ev, frame,
timeval_current_ofs(0, 0),
test_free_wrapper_timer_handler, NULL);
torture_assert_not_null_goto(tctx, te, ok, done,
"tevent_add_timer failed\n");
im = tevent_create_immediate(frame);
torture_assert_not_null_goto(tctx, im, ok, done,
"tevent_create_immediate failed\n");
se = tevent_add_signal(wrap_ev, frame,
SIGUSR1,
0,
test_free_wrapper_signal_handler,
tctx);
torture_assert_not_null_goto(tctx, se, ok, done,
"tevent_add_signal failed\n");
do_write(sock[0], &c, 1);
kill(getpid(), SIGUSR1);
tevent_schedule_immediate(im,
wrap_ev,
test_free_wrapper_immediate_handler,
NULL);
ret = tevent_loop_wait(ev);
torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n");
ok = true;
done:
TALLOC_FREE(frame);
if (sock[0] != -1) {
close(sock[0]);
}
if (sock[1] != -1) {
close(sock[1]);
}
return ok;
}
#ifdef HAVE_PTHREAD
static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -1636,6 +1789,10 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
"wrapper",
test_wrapper,
(const void *)list[i]);
torture_suite_add_simple_tcase_const(backend_suite,
"free_wrapper",
test_free_wrapper,
(const void *)list[i]);
torture_suite_add_suite(suite, backend_suite);
}