]> granicus.if.org Git - libevent/commitdiff
IOCP-related unit test tweaks
authorChristopher Davis <chrisd@torproject.org>
Sat, 28 Aug 2010 09:44:11 +0000 (02:44 -0700)
committerChristopher Davis <chrisd@torproject.org>
Wed, 8 Sep 2010 08:22:22 +0000 (01:22 -0700)
test/regress_bufferevent.c
test/regress_iocp.c

index 370eee01d5d577df34830165ac170176ae495a52..de97909f632a6c17af443140a6bdf1b8b64443aa 100644 (file)
@@ -426,9 +426,8 @@ listen_cb(struct evconnlistener *listener, evutil_socket_t fd,
        TT_BLATHER(("Got a request on socket %d", (int)fd ));
        bev = bufferevent_socket_new(base, fd, bufferevent_connect_test_flags);
        tt_assert(bev);
-       bufferevent_write(bev, s, sizeof(s));
        bufferevent_setcb(bev, NULL, sender_writecb, sender_errorcb, NULL);
-       bufferevent_enable(bev, EV_WRITE);
+       bufferevent_write(bev, s, sizeof(s));
 end:
        ;
 }
@@ -527,13 +526,6 @@ test_bufferevent_connect(void *arg)
        tt_want(!bufferevent_socket_connect(bev1, sa, sizeof(localhost)));
        tt_want(!bufferevent_socket_connect(bev2, sa, sizeof(localhost)));
 
-#ifdef WIN32
-       /* FIXME this is to get IOCP to work. it shouldn't be required. */
-       {
-               struct timeval tv = {5000,0};
-               event_base_loopexit(data->base, &tv);
-       }
-#endif
        event_base_dispatch(data->base);
 
        tt_int_op(n_strings_read, ==, 2);
@@ -622,13 +614,6 @@ test_bufferevent_connect_fail(void *arg)
        event_add(&close_listener_event, &one_second);
        close_listener_event_added = 1;
 
-#ifdef WIN32
-       /* FIXME this is to get IOCP to work. it shouldn't be required. */
-       {
-               struct timeval tv = {5000,0};
-               event_base_loopexit(data->base, &tv);
-       }
-#endif
        event_base_dispatch(data->base);
 
        tt_int_op(test_ok, ==, 1);
index 59aeab0b45dc27d153c6bd9b7bcf9ef90914f48f..96d8eb3edf58a733c33eefafff657deeb37d7776 100644 (file)
@@ -29,6 +29,7 @@
 #include <event2/event.h>
 #include <event2/thread.h>
 #include <event2/buffer.h>
+#include <event2/buffer_compat.h>
 #include <event2/bufferevent.h>
 
 #include <winsock2.h>
@@ -44,6 +45,7 @@
 #undef WIN32_LEAN_AND_MEAN
 
 #include "iocp-internal.h"
+#include "evbuffer-internal.h"
 #include "evthread-internal.h"
 
 /* FIXME remove these ones */
 #include "event-internal.h"
 
 #define MAX_CALLS 16
+
+static void *count_lock = NULL, *count_cond = NULL;
+static int count = 0;
+
+static void
+count_init(void)
+{
+       EVTHREAD_ALLOC_LOCK(count_lock, 0);
+       EVTHREAD_ALLOC_COND(count_cond);
+
+       tt_assert(count_lock);
+       tt_assert(count_cond);
+
+end:
+       ;
+}
+
+static void
+count_free(void)
+{
+       EVTHREAD_FREE_LOCK(count_lock, 0);
+       EVTHREAD_FREE_COND(count_cond);
+}
+
+static void
+count_incr(void)
+{
+       EVLOCK_LOCK(count_lock, 0);
+       count++;
+       EVTHREAD_COND_BROADCAST(count_cond);
+       EVLOCK_UNLOCK(count_lock, 0);
+}
+
+static int
+count_wait_for(int i, int ms)
+{
+       struct timeval tv;
+       DWORD elapsed;
+       int rv = -1;
+
+       EVLOCK_LOCK(count_lock, 0);
+       while (ms > 0 && count != i) {
+               tv.tv_sec = 0;
+               tv.tv_usec = ms * 1000;
+               elapsed = GetTickCount();
+               EVTHREAD_COND_WAIT_TIMED(count_cond, count_lock, &tv);
+               elapsed = GetTickCount() - elapsed;
+               ms -= elapsed;
+       }
+       if (count == i)
+               rv = 0;
+       EVLOCK_UNLOCK(count_lock, 0);
+
+       return rv;
+}
+
 struct dummy_overlapped {
        struct event_overlapped eo;
        void *lock;
@@ -73,6 +131,8 @@ dummy_cb(struct event_overlapped *o, uintptr_t key, ev_ssize_t n, int ok)
        }
        d_o->call_count++;
        EVLOCK_UNLOCK(d_o->lock, 0);
+
+       count_incr();
 }
 
 static int
@@ -100,6 +160,7 @@ test_iocp_port(void *ptr)
        memset(&o1, 0, sizeof(o1));
        memset(&o2, 0, sizeof(o2));
 
+       count_init();
        EVTHREAD_ALLOC_LOCK(o1.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
        EVTHREAD_ALLOC_LOCK(o2.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
 
@@ -124,10 +185,7 @@ test_iocp_port(void *ptr)
        tt_assert(!event_iocp_activate_overlapped(port, &o1.eo, 13, 103));
        tt_assert(!event_iocp_activate_overlapped(port, &o2.eo, 23, 203));
 
-#ifdef WIN32
-       /* FIXME Be smarter. */
-       Sleep(1000);
-#endif
+       tt_int_op(count_wait_for(8, 2000), ==, 0);
 
        tt_want(!event_iocp_shutdown(port, 2000));
 
@@ -145,8 +203,9 @@ test_iocp_port(void *ptr)
        tt_want(pair_is_in(&o2, 23, 203));
 
 end:
-       /* FIXME free the locks. */
-       ;
+       EVTHREAD_FREE_LOCK(o1.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
+       EVTHREAD_FREE_LOCK(o2.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
+       count_free();
 }
 
 static struct evbuffer *rbuf = NULL, *wbuf = NULL;
@@ -157,6 +216,7 @@ read_complete(struct event_overlapped *eo, uintptr_t key,
 {
        tt_assert(ok);
        evbuffer_commit_read(rbuf, nbytes);
+       count_incr();
 end:
        ;
 }
@@ -167,6 +227,7 @@ write_complete(struct event_overlapped *eo, uintptr_t key,
 {
        tt_assert(ok);
        evbuffer_commit_write(wbuf, nbytes);
+       count_incr();
 end:
        ;
 }
@@ -177,9 +238,12 @@ test_iocp_evbuffer(void *ptr)
        struct event_overlapped rol, wol;
        struct basic_test_data *data = ptr;
        struct event_iocp_port *port = NULL;
+       struct evbuffer *buf;
+       struct evbuffer_chain *chain;
        char junk[1024];
        int i;
 
+       count_init();
        event_overlapped_init(&rol, read_complete);
        event_overlapped_init(&wol, write_complete);
 
@@ -202,14 +266,18 @@ test_iocp_evbuffer(void *ptr)
        for (i=0;i<10;++i)
                evbuffer_add(wbuf, junk, sizeof(junk));
 
+       buf = evbuffer_new();
+       tt_assert(buf != NULL);
+       evbuffer_add(rbuf, junk, sizeof(junk));
+       tt_assert(!evbuffer_launch_read(rbuf, 2048, &rol));
+       evbuffer_add_buffer(buf, rbuf);
+       tt_int_op(evbuffer_get_length(buf), ==, sizeof(junk));
+       for (chain = buf->first; chain; chain = chain->next)
+               tt_int_op(chain->flags & EVBUFFER_MEM_PINNED_ANY, ==, 0);
        tt_assert(!evbuffer_get_length(rbuf));
        tt_assert(!evbuffer_launch_write(wbuf, 512, &wol));
-       tt_assert(!evbuffer_launch_read(rbuf, 2048, &rol));
 
-#ifdef WIN32
-       /* FIXME this is stupid. */
-       Sleep(1000);
-#endif
+       tt_int_op(count_wait_for(2, 2000), ==, 0);
 
        tt_int_op(evbuffer_get_length(rbuf),==,512);
 
@@ -217,8 +285,20 @@ test_iocp_evbuffer(void *ptr)
 
        tt_want(!event_iocp_shutdown(port, 2000));
 end:
+       count_free();
        evbuffer_free(rbuf);
        evbuffer_free(wbuf);
+       evbuffer_free(buf);
+}
+
+static int got_readcb = 0;
+
+static void
+async_readcb(struct bufferevent *bev, void *arg)
+{
+       /* Disabling read should cause the loop to quit */
+       bufferevent_disable(bev, EV_READ);
+       got_readcb++;
 }
 
 static void
@@ -229,7 +309,6 @@ test_iocp_bufferevent_async(void *ptr)
        struct bufferevent *bea1=NULL, *bea2=NULL;
        char buf[128];
        size_t n;
-       struct timeval one_sec = {1,0};
 
        event_base_start_iocp(data->base);
        port = event_base_get_iocp(data->base);
@@ -242,26 +321,27 @@ test_iocp_bufferevent_async(void *ptr)
        tt_assert(bea1);
        tt_assert(bea2);
 
-       /*FIXME set some callbacks */
+       bufferevent_setcb(bea2, async_readcb, NULL, NULL, NULL);
        bufferevent_enable(bea1, EV_WRITE);
        bufferevent_enable(bea2, EV_READ);
 
        bufferevent_write(bea1, "Hello world", strlen("Hello world")+1);
 
-       event_base_loopexit(data->base, &one_sec);
        event_base_dispatch(data->base);
 
+       tt_int_op(got_readcb, ==, 1);
        n = bufferevent_read(bea2, buf, sizeof(buf)-1);
        buf[n]='\0';
        tt_str_op(buf, ==, "Hello world");
 
 end:
-       /* FIXME: free stuff. */;
+       bufferevent_free(bea1);
+       bufferevent_free(bea2);
 }
 
 
 struct testcase_t iocp_testcases[] = {
-       { "port", test_iocp_port, TT_FORK|TT_NEED_THREADS, NULL, NULL },
+       { "port", test_iocp_port, TT_FORK|TT_NEED_THREADS, &basic_setup, NULL },
        { "evbuffer", test_iocp_evbuffer,
          TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_THREADS,
          &basic_setup, NULL },