mirror of
https://github.com/libevent/libevent.git
synced 2025-01-09 00:56:20 +08:00
Improve testing of when thread-notification occurs
This commit is contained in:
parent
4632b78e01
commit
ce85280beb
@ -62,6 +62,7 @@
|
||||
#include "event2/buffer_compat.h"
|
||||
#include "event2/util.h"
|
||||
#include "event-internal.h"
|
||||
#include "evthread-internal.h"
|
||||
#include "util-internal.h"
|
||||
#include "log-internal.h"
|
||||
|
||||
@ -805,6 +806,9 @@ test_fork(void)
|
||||
|
||||
setup_test("After fork: ");
|
||||
|
||||
tt_assert(current_base);
|
||||
evthread_make_base_notifiable(current_base);
|
||||
|
||||
write(pair[0], TEST1, strlen(TEST1)+1);
|
||||
|
||||
event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
|
||||
@ -863,6 +867,7 @@ test_fork(void)
|
||||
|
||||
evsignal_del(&sig_ev);
|
||||
|
||||
end:
|
||||
cleanup_test();
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,18 @@
|
||||
#include <process.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#ifdef _EVENT_HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "sys/queue.h"
|
||||
|
||||
#include "event2/util.h"
|
||||
#include "event2/event.h"
|
||||
#include "event2/event_struct.h"
|
||||
#include "event2/thread.h"
|
||||
#include "evthread-internal.h"
|
||||
#include "event-internal.h"
|
||||
#include "regress.h"
|
||||
#include "tinytest_macros.h"
|
||||
|
||||
@ -131,7 +137,7 @@ basic_thread(void *arg)
|
||||
|
||||
/* exit the loop only if all threads fired all timeouts */
|
||||
EVLOCK_LOCK(count_lock, 0);
|
||||
if (count >= NUM_THREADS * 100)
|
||||
if (count >= NUM_THREADS * NUM_ITERATIONS)
|
||||
event_base_loopexit(base, NULL);
|
||||
EVLOCK_UNLOCK(count_lock, 0);
|
||||
|
||||
@ -141,6 +147,27 @@ basic_thread(void *arg)
|
||||
THREAD_RETURN();
|
||||
}
|
||||
|
||||
static int got_sigchld = 0;
|
||||
static void
|
||||
sigchld_cb(evutil_socket_t fd, short event, void *arg)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct event_base *base = arg;
|
||||
|
||||
got_sigchld++;
|
||||
tv.tv_usec = 100000;
|
||||
tv.tv_sec = 0;
|
||||
event_base_loopexit(base, &tv);
|
||||
}
|
||||
|
||||
|
||||
static int notification_fd_used = 0;
|
||||
static void
|
||||
notify_fd_cb(evutil_socket_t fd, short event, void *arg)
|
||||
{
|
||||
++notification_fd_used;
|
||||
}
|
||||
|
||||
static void
|
||||
thread_basic(void *arg)
|
||||
{
|
||||
@ -151,6 +178,10 @@ thread_basic(void *arg)
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
|
||||
int forking = data->setup_data && !strcmp(data->setup_data, "forking");
|
||||
struct event *notification_event = NULL;
|
||||
struct event *sigchld_event = NULL;
|
||||
|
||||
EVTHREAD_ALLOC_LOCK(count_lock, 0);
|
||||
tt_assert(count_lock);
|
||||
|
||||
@ -159,6 +190,42 @@ thread_basic(void *arg)
|
||||
tt_abort_msg("Couldn't make base notifiable!");
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (forking) {
|
||||
pid_t pid;
|
||||
int status;
|
||||
sigchld_event = evsignal_new(base, SIGCHLD, sigchld_cb, base);
|
||||
/* This piggybacks on the th_notify_fd weirdly, and looks
|
||||
* inside libevent internals. Not a good idea in non-testing
|
||||
* code! */
|
||||
notification_event = event_new(base,
|
||||
base->th_notify_fd[0], EV_READ|EV_PERSIST, notify_fd_cb,
|
||||
NULL);
|
||||
event_add(sigchld_event, NULL);
|
||||
event_add(notification_event, NULL);
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
if (event_reinit(base) < 0) {
|
||||
TT_FAIL(("reinit"));
|
||||
exit(1);
|
||||
}
|
||||
goto child;
|
||||
}
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
tt_abort_perror("waitpid");
|
||||
TT_BLATHER(("Waitpid okay\n"));
|
||||
|
||||
tt_assert(got_sigchld);
|
||||
tt_int_op(notification_fd_used, ==, 0);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
child:
|
||||
#endif
|
||||
for (i = 0; i < NUM_THREADS; ++i)
|
||||
THREAD_START(threads[i], basic_thread, base);
|
||||
|
||||
@ -177,8 +244,15 @@ thread_basic(void *arg)
|
||||
tt_int_op(count, ==, NUM_THREADS * NUM_ITERATIONS);
|
||||
|
||||
EVTHREAD_FREE_LOCK(count_lock, 0);
|
||||
|
||||
TT_BLATHER(("notifiations==%d", notification_fd_used));
|
||||
|
||||
end:
|
||||
;
|
||||
|
||||
if (notification_event)
|
||||
event_free(notification_event);
|
||||
if (sigchld_event)
|
||||
event_free(sigchld_event);
|
||||
}
|
||||
|
||||
#undef NUM_THREADS
|
||||
@ -313,10 +387,16 @@ end:
|
||||
}
|
||||
|
||||
#define TEST(name) \
|
||||
{ #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, \
|
||||
&basic_setup, NULL }
|
||||
{ #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, \
|
||||
&basic_setup, NULL }
|
||||
|
||||
struct testcase_t thread_testcases[] = {
|
||||
TEST(basic),
|
||||
{ "basic", thread_basic, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE,
|
||||
&basic_setup, NULL },
|
||||
#ifndef WIN32
|
||||
{ "forking", thread_basic, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE,
|
||||
&basic_setup, (char*)"forking" },
|
||||
#endif
|
||||
TEST(conditions_simple),
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user