fixes #446 efd_win.inc global critical section should be mutex
fixes #485 Windows efd_init should not assert on failure
fixes #484 Make tcp_shutdown a little less likely to hang forever
fixes #483 CMake tests hang forever
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f46fc56..a575468 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,6 +60,7 @@
     add_executable (${NAME} tests/${NAME}.c)
     target_link_libraries (${NAME} nanomsg)
     add_test (NAME ${NAME} COMMAND ${NAME})
+    set_tests_properties (${NAME} PROPERTIES  TIMEOUT 30)
 endmacro (add_libnanomsg_test)
 
 #  Transport tests.
diff --git a/src/utils/efd_win.inc b/src/utils/efd_win.inc
index 8d25340..4978c76 100644
--- a/src/utils/efd_win.inc
+++ b/src/utils/efd_win.inc
@@ -56,15 +56,24 @@
 
     /*  This function has to be enclosed in a system-wide critical section
         so that two instances of the library don't accidentally create an efd
-        crossing the process boundary. 
-        CAUTION: This critical section has machine-wide scope. Thus, it must
-        be properly exited even before crashing the process by an assertion. */
-    sync = CreateEvent (&sa, FALSE, TRUE, "Global\\nanomsg-port-sync");
+        crossing the process boundary. */
+    sync = CreateMutex (&sa, FALSE, "Global\\nanomsg-port-mutex");
     win_assert (sync != NULL);
 
-    /*  Enter the critical section. */
-    dwrc = WaitForSingleObject (sync, INFINITE);
-    nn_assert (dwrc == WAIT_OBJECT_0);
+    /*  Enter the critical section.   If we cannot get the object in 10 seconds
+        then something is seriously wrong.  Just bail. */
+    dwrc = WaitForSingleObject (sync, 10000);
+    switch (dwrc) {
+    case WAIT_ABANDONED:
+    case WAIT_OBJECT_0:
+        break;
+    case WAIT_TIMEOUT:
+        rc = ETIMEDOUT;
+        goto wsafail3;
+    default:
+        rc = nn_err_wsa_to_posix (WSAGetLastError ());
+        goto wsafail3;
+    }
 
     /*  Unfortunately, on Windows the only way to send signal to a file
         descriptor (SOCKET) is to create a full-blown TCP connecting on top of
@@ -141,7 +150,7 @@
     if (i == NN_EFD_RETRIES)
         goto wsafail2;
 
-    while (1) {
+    for (;;) {
 
         /*  Accept new incoming connection. */
         addrlen = sizeof (addr);
@@ -166,7 +175,7 @@
         goto wsafail;
 
     /*  Leave the critical section. */
-    brc = SetEvent (sync);
+    brc = ReleaseMutex (sync);
     win_assert (brc != 0);
     brc = CloseHandle (sync);
     win_assert (brc != 0);
@@ -184,11 +193,11 @@
 wsafail:
     rc = nn_err_wsa_to_posix (WSAGetLastError ());
 wsafail2:
-    brc = SetEvent (sync);
+    brc = ReleaseMutex (sync);
     win_assert (brc != 0);
+wsafail3:
     brc = CloseHandle (sync);
     win_assert (brc != 0);
-    errnum_assert (0, rc);
     return -rc;
 }
 
diff --git a/tests/tcp_shutdown.c b/tests/tcp_shutdown.c
index bd28ef9..24339aa 100644
--- a/tests/tcp_shutdown.c
+++ b/tests/tcp_shutdown.c
@@ -57,13 +57,19 @@
 {
     int s;
     int i;
+    int ms;
 
     s = test_socket (AF_SP, NN_PULL);
 
-    for (i = 0; i < 10; ++i) {
+    /*  On AppVeyor/Windows, if this is 10, we get timeouts trying to
+        establish the connection.  This value (5) seems to work though. */
+    for (i = 0; i < 5; ++i) {
         test_connect (s, SOCKET_ADDRESS);
     }
 
+    ms = 2000;
+    test_setsockopt (s, NN_SOL_SOCKET, NN_RCVTIMEO, &ms, sizeof (ms));
+
     for (i = 0; i < MESSAGES_PER_THREAD; ++i) {
         test_recv (s, "hello");
     }
@@ -91,8 +97,9 @@
     for (j = 0; j != TEST_LOOPS; ++j) {
         for (i = 0; i != THREAD_COUNT; ++i)
             nn_thread_init (&threads [i], routine, NULL);
-        for (i = 0; i != THREAD_COUNT; ++i)
+        for (i = 0; i != THREAD_COUNT; ++i) {
             nn_thread_term (&threads [i]);
+	}
     }
 
     test_close (sb);
@@ -103,10 +110,13 @@
     test_bind (sb, SOCKET_ADDRESS);
 
     for (j = 0; j != TEST_LOOPS; ++j) {
+	int ms;
         for (i = 0; i != TEST2_THREAD_COUNT; ++i)
-            nn_thread_init (&threads [i], routine2, NULL);
+            nn_thread_init (&threads [i], routine2, &threads[i]);
         nn_atomic_init(&active, TEST2_THREAD_COUNT);
 
+	ms = 2000;
+	test_setsockopt (sb, NN_SOL_SOCKET, NN_SNDTIMEO, &ms, sizeof (ms));
         while (active.n) {
             (void) nn_send (sb, "hello", 5, NN_DONTWAIT);
         }
diff --git a/tests/testutil.h b/tests/testutil.h
index fe6aba1..89e5247 100644
--- a/tests/testutil.h
+++ b/tests/testutil.h
@@ -33,6 +33,8 @@
 static void test_close_impl (char *file, int line, int sock);
 static void test_send_impl (char *file, int line, int sock, char *data);
 static void test_recv_impl (char *file, int line, int sock, char *data);
+static int  test_setsockopt_impl (char *file, int line, int sock, int level,
+    int option, const void *optval, size_t optlen);
 
 #define test_socket(f, p) test_socket_impl (__FILE__, __LINE__, (f), (p))
 #define test_connect(s, a) test_connect_impl (__FILE__, __LINE__, (s), (a))
@@ -40,6 +42,8 @@
 #define test_send(s, d) test_send_impl (__FILE__, __LINE__, (s), (d))
 #define test_recv(s, d) test_recv_impl (__FILE__, __LINE__, (s), (d))
 #define test_close(s) test_close_impl (__FILE__, __LINE__, (s))
+#define test_setsockopt(s, l, o, v, z) test_setsockopt_impl (__FILE__, \
+    __LINE__, (s), (l), (o), (v), (z))
 
 static int NN_UNUSED test_socket_impl (char *file, int line, int family,
     int protocol)
@@ -89,6 +93,22 @@
     return rc;
 }
 
+static int NN_UNUSED test_setsockopt_impl (char *file, int line,
+    int sock, int level, int option, const void *optval, size_t optlen)
+{
+    int rc;
+
+    rc = nn_setsockopt (sock, level, option, optval, optlen);
+    if(rc < 0) {
+        fprintf (stderr, "Failed set option \"%d\": %s [%d] (%s:%d)\n",
+            option,
+            nn_err_strerror (errno),
+            (int) errno, file, line);
+        nn_err_abort ();
+    }
+    return rc;
+}
+
 static void NN_UNUSED test_close_impl (char *file, int line, int sock)
 {
     int rc;