summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-07-30 09:09:46 +0200
committerStefan Metzmacher <metze@samba.org>2012-08-16 20:52:17 +0200
commitd7af2c842a5db2a1dd9f61b463ccfee24d7db5ed (patch)
tree212572dfd74bb54af6fcf3b915cd069aab89de8c /lib
parentfa71f3241110fbe079de6d6cb0c8f3df001f4c65 (diff)
downloadsamba-d7af2c842a5db2a1dd9f61b463ccfee24d7db5ed.tar.gz
samba-d7af2c842a5db2a1dd9f61b463ccfee24d7db5ed.tar.bz2
samba-d7af2c842a5db2a1dd9f61b463ccfee24d7db5ed.zip
tevent: Add threaded poll_mt testcase
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/tevent/testsuite.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index 5868f0a9fe..3d2a79adcf 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -26,7 +26,12 @@
#include "includes.h"
#include "lib/tevent/tevent.h"
#include "system/filesys.h"
+#include "system/select.h"
#include "torture/torture.h"
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#include <assert.h>
+#endif
static int fde_count;
@@ -146,6 +151,140 @@ static bool test_event_context(struct torture_context *test,
return true;
}
+#ifdef HAVE_PTHREAD
+
+static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
+static bool do_shutdown = false;
+
+static void test_event_threaded_lock(void)
+{
+ int ret;
+ ret = pthread_mutex_lock(&threaded_mutex);
+ assert(ret == 0);
+}
+
+static void test_event_threaded_unlock(void)
+{
+ int ret;
+ ret = pthread_mutex_unlock(&threaded_mutex);
+ assert(ret == 0);
+}
+
+static void test_event_threaded_trace(enum tevent_trace_point point,
+ void *private_data)
+{
+ switch (point) {
+ case TEVENT_TRACE_BEFORE_WAIT:
+ test_event_threaded_unlock();
+ break;
+ case TEVENT_TRACE_AFTER_WAIT:
+ test_event_threaded_lock();
+ break;
+ }
+}
+
+static void test_event_threaded_timer(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data)
+{
+ return;
+}
+
+static void *test_event_poll_thread(void *private_data)
+{
+ struct tevent_context *ev = (struct tevent_context *)private_data;
+
+ test_event_threaded_lock();
+
+ while (true) {
+ int ret;
+ ret = tevent_loop_once(ev);
+ assert(ret == 0);
+ if (do_shutdown) {
+ test_event_threaded_unlock();
+ return NULL;
+ }
+ }
+
+}
+
+static void test_event_threaded_read_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ int *pfd = (int *)private_data;
+ char c;
+ ssize_t nread;
+
+ if ((flags & TEVENT_FD_READ) == 0) {
+ return;
+ }
+
+ do {
+ nread = read(*pfd, &c, 1);
+ } while ((nread == -1) && (errno == EINTR));
+
+ assert(nread == 1);
+}
+
+static bool test_event_context_threaded(struct torture_context *test,
+ const void *test_data)
+{
+ struct tevent_context *ev;
+ struct tevent_timer *te;
+ struct tevent_fd *fde;
+ pthread_t poll_thread;
+ int fds[2];
+ int ret;
+ char c = 0;
+
+ ev = tevent_context_init_byname(test, "poll_mt");
+ torture_assert(test, ev != NULL, "poll_mt not supported");
+
+ tevent_set_trace_callback(ev, test_event_threaded_trace, NULL);
+
+ te = tevent_add_timer(ev, ev, timeval_current_ofs(5, 0),
+ test_event_threaded_timer, NULL);
+ torture_assert(test, te != NULL, "Could not add timer");
+
+ ret = pthread_create(&poll_thread, NULL, test_event_poll_thread, ev);
+ torture_assert(test, ret == 0, "Could not create poll thread");
+
+ ret = pipe(fds);
+ torture_assert(test, ret == 0, "Could not create pipe");
+
+ poll(NULL, 0, 100);
+
+ test_event_threaded_lock();
+
+ fde = tevent_add_fd(ev, ev, fds[0], TEVENT_FD_READ,
+ test_event_threaded_read_handler, &fds[0]);
+ torture_assert(test, fde != NULL, "Could not add fd event");
+
+ test_event_threaded_unlock();
+
+ poll(NULL, 0, 100);
+
+ write(fds[1], &c, 1);
+
+ poll(NULL, 0, 100);
+
+ test_event_threaded_lock();
+ do_shutdown = true;
+ test_event_threaded_unlock();
+
+ write(fds[1], &c, 1);
+
+ ret = pthread_join(poll_thread, NULL);
+ torture_assert(test, ret == 0, "pthread_join failed");
+
+ return true;
+}
+
+#endif
+
struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
{
struct torture_suite *suite = torture_suite_create(mem_ctx, "event");
@@ -158,5 +297,11 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
(const void *)list[i]);
}
+#ifdef HAVE_PTHREAD
+ torture_suite_add_simple_tcase_const(suite, "poll_mt_threaded",
+ test_event_context_threaded,
+ NULL);
+#endif
+
return suite;
}