[glib] gsocket: add a testcase that shows a hang on win32
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gsocket: add a testcase that shows a hang on win32
- Date: Sat, 17 Jan 2015 14:05:39 +0000 (UTC)
commit 4f4714285dcc5c3ce9c87f65d9f684f285113a6e
Author: Paolo Borelli <pborelli gnome org>
Date: Sat Jan 10 15:23:07 2015 +0100
gsocket: add a testcase that shows a hang on win32
Add a unit test that checks g_socket_new_from_fd by creating
a gsocket, obtaining its fd, duplicating the fd and then creating
a gsocket from the new fd. This shows a hang on win32 since the
gsocket created from the fd never receives the FD_WRITE event
because we wait for the condition without first trying to write
and windows signals the condition only after a EWOULDBLOCK error.
https://bugzilla.gnome.org/show_bug.cgi?id=741707
gio/tests/socket.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
---
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index 4c3f69b..a1f48bc 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -929,6 +929,99 @@ test_timed_wait (void)
g_slice_free (IPTestData, data);
}
+static int
+duplicate_fd(int fd)
+{
+#ifdef G_OS_WIN32
+ HANDLE newfd;
+
+ if (!DuplicateHandle (GetCurrentProcess (),
+ (HANDLE)fd,
+ GetCurrentProcess (),
+ &newfd,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS))
+ {
+ return -1;
+ }
+
+ return (int)newfd;
+#else
+ return dup(fd);
+#endif
+}
+
+static void
+test_fd_roundtrip (void)
+{
+ IPTestData *data;
+ GError *error = NULL;
+ GSocket *client;
+ GSocket *client2;
+ GSocketAddress *addr;
+ int fd;
+ gssize len;
+ gchar buf[128];
+
+ data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE);
+ addr = g_socket_get_local_address (data->server, &error);
+ g_assert_no_error (error);
+
+ client = g_socket_new (G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT,
+ &error);
+ g_assert_no_error (error);
+
+ g_socket_set_blocking (client, TRUE);
+ g_socket_set_timeout (client, 1);
+
+ g_socket_connect (client, addr, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_socket_is_connected (client));
+ g_object_unref (addr);
+
+ /* we have to dup otherwise the fd gets closed twice on unref */
+ fd = duplicate_fd (g_socket_get_fd (client));
+ client2 = g_socket_new_from_fd (fd, &error);
+ g_assert_no_error (error);
+
+ g_assert_cmpint (g_socket_get_family (client2), ==, g_socket_get_family (client));
+ g_assert_cmpint (g_socket_get_socket_type (client2), ==, g_socket_get_socket_type (client));
+ g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP);
+
+ len = g_socket_send (client2, testbuf, strlen (testbuf) + 1, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (len, ==, strlen (testbuf) + 1);
+
+ len = g_socket_receive (client2, buf, sizeof (buf), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (len, ==, strlen (testbuf) + 1);
+
+ g_assert_cmpstr (testbuf, ==, buf);
+
+ g_socket_shutdown (client, FALSE, TRUE, &error);
+ g_assert_no_error (error);
+ g_socket_shutdown (client2, FALSE, TRUE, &error);
+ g_assert_no_error (error);
+
+ g_thread_join (data->thread);
+
+ g_socket_close (client, &error);
+ g_assert_no_error (error);
+ g_socket_close (client2, &error);
+ g_assert_no_error (error);
+ g_socket_close (data->server, &error);
+ g_assert_no_error (error);
+
+ g_object_unref (data->server);
+ g_object_unref (client);
+ g_object_unref (client2);
+
+ g_slice_free (IPTestData, data);
+}
+
static void
test_sockaddr (void)
{
@@ -1355,6 +1448,7 @@ main (int argc,
#endif
g_test_add_func ("/socket/close_graceful", test_close_graceful);
g_test_add_func ("/socket/timed_wait", test_timed_wait);
+ g_test_add_func ("/socket/fd_roundtrip", test_fd_roundtrip);
g_test_add_func ("/socket/address", test_sockaddr);
#ifdef G_OS_UNIX
g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]