From 2131facaaba43a022dea96e4641748b2a5eed2b4 Mon Sep 17 00:00:00 2001 From: Ignacio Casal Quinteiro Date: Tue, 23 Dec 2014 08:41:13 +0100 Subject: [PATCH] glib2: fix hang on gsocket --- ...-block-when-errno-says-it-will-block.patch | 274 ++++++++++++++++++ mingw-w64-glib2/PKGBUILD | 9 +- 2 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 mingw-w64-glib2/0001-gsocket-block-when-errno-says-it-will-block.patch diff --git a/mingw-w64-glib2/0001-gsocket-block-when-errno-says-it-will-block.patch b/mingw-w64-glib2/0001-gsocket-block-when-errno-says-it-will-block.patch new file mode 100644 index 0000000000..6cd226dd1b --- /dev/null +++ b/mingw-w64-glib2/0001-gsocket-block-when-errno-says-it-will-block.patch @@ -0,0 +1,274 @@ +From 177ff38e103a76b7cd153c4c8014159eb6a9eb60 Mon Sep 17 00:00:00 2001 +From: Ignacio Casal Quinteiro +Date: Mon, 22 Dec 2014 16:38:50 +0100 +Subject: [PATCH] gsocket: block when errno says it will block + +On windows it may happen we recreate a gsocket +out of a fd from another gsocket that already +got the FD_WRITE event. If this happens in order +to get another FD_WRITE we need to have tried an +operation that might need such event. What we do +here is to first try to do the operation and +then if errno specifies that we might block then +wait for that event to occur. + +https://bugzilla.gnome.org/show_bug.cgi?id=741707 +--- + gio/gsocket.c | 147 ++++++++++++++++++++++++++++++---------------------------- + 1 file changed, 77 insertions(+), 70 deletions(-) + +diff --git a/gio/gsocket.c b/gio/gsocket.c +index d9e135d..f144674 100644 +--- a/gio/gsocket.c ++++ b/gio/gsocket.c +@@ -2230,31 +2230,31 @@ g_socket_accept (GSocket *socket, + + while (TRUE) + { +- if (socket->priv->blocking && +- !g_socket_condition_wait (socket, +- G_IO_IN, cancellable, error)) +- return NULL; +- + if ((ret = accept (socket->priv->fd, NULL, 0)) < 0) + { + int errsv = get_socket_errno (); + +- win32_unset_event_mask (socket, FD_ACCEPT); +- + if (errsv == EINTR) + continue; + +- if (socket->priv->blocking) +- { + #ifdef WSAEWOULDBLOCK +- if (errsv == WSAEWOULDBLOCK) +- continue; ++ if (errsv == WSAEWOULDBLOCK) + #else +- if (errsv == EWOULDBLOCK || +- errsv == EAGAIN) +- continue; ++ if (errsv == EWOULDBLOCK || ++ errsv == EAGAIN) + #endif +- } ++ { ++ win32_unset_event_mask (socket, FD_ACCEPT); ++ ++ if (socket->priv->blocking) ++ { ++ if (!g_socket_condition_wait (socket, ++ G_IO_IN, cancellable, error)) ++ return NULL; ++ ++ continue; ++ } ++ } + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), +@@ -2368,6 +2368,8 @@ g_socket_connect (GSocket *socket, + if (errsv == WSAEWOULDBLOCK) + #endif + { ++ win32_unset_event_mask (socket, FD_CONNECT); ++ + if (socket->priv->blocking) + { + if (g_socket_condition_wait (socket, G_IO_OUT, cancellable, error)) +@@ -2602,11 +2604,6 @@ g_socket_receive_with_blocking (GSocket *socket, + + while (1) + { +- if (blocking && +- !g_socket_condition_wait (socket, +- G_IO_IN, cancellable, error)) +- return -1; +- + if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0) + { + int errsv = get_socket_errno (); +@@ -2614,17 +2611,24 @@ g_socket_receive_with_blocking (GSocket *socket, + if (errsv == EINTR) + continue; + +- if (blocking) +- { + #ifdef WSAEWOULDBLOCK +- if (errsv == WSAEWOULDBLOCK) +- continue; ++ if (errsv == WSAEWOULDBLOCK) + #else +- if (errsv == EWOULDBLOCK || +- errsv == EAGAIN) +- continue; ++ if (errsv == EWOULDBLOCK || ++ errsv == EAGAIN) + #endif +- } ++ { ++ win32_unset_event_mask (socket, FD_READ); ++ ++ if (blocking) ++ { ++ if (!g_socket_condition_wait (socket, ++ G_IO_IN, cancellable, error)) ++ return -1; ++ ++ continue; ++ } ++ } + + win32_unset_event_mask (socket, FD_READ); + +@@ -2777,11 +2781,6 @@ g_socket_send_with_blocking (GSocket *socket, + + while (1) + { +- if (blocking && +- !g_socket_condition_wait (socket, +- G_IO_OUT, cancellable, error)) +- return -1; +- + if ((ret = send (socket->priv->fd, buffer, size, G_SOCKET_DEFAULT_SEND_FLAGS)) < 0) + { + int errsv = get_socket_errno (); +@@ -2790,21 +2789,23 @@ g_socket_send_with_blocking (GSocket *socket, + continue; + + #ifdef WSAEWOULDBLOCK +- if (errsv == WSAEWOULDBLOCK) +- win32_unset_event_mask (socket, FD_WRITE); +-#endif +- +- if (blocking) +- { +-#ifdef WSAEWOULDBLOCK +- if (errsv == WSAEWOULDBLOCK) +- continue; ++ if (errsv == WSAEWOULDBLOCK) + #else +- if (errsv == EWOULDBLOCK || +- errsv == EAGAIN) +- continue; ++ if (errsv == EWOULDBLOCK || ++ errsv == EAGAIN) + #endif +- } ++ { ++ win32_unset_event_mask (socket, FD_WRITE); ++ ++ if (blocking) ++ { ++ if (!g_socket_condition_wait (socket, ++ G_IO_OUT, cancellable, error)) ++ return -1; ++ ++ continue; ++ } ++ } + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), +@@ -3874,11 +3875,6 @@ g_socket_send_message (GSocket *socket, + + while (1) + { +- if (socket->priv->blocking && +- !g_socket_condition_wait (socket, +- G_IO_OUT, cancellable, error)) +- return -1; +- + result = sendmsg (socket->priv->fd, &msg, flags | G_SOCKET_DEFAULT_SEND_FLAGS); + if (result < 0) + { +@@ -3890,7 +3886,13 @@ g_socket_send_message (GSocket *socket, + if (socket->priv->blocking && + (errsv == EWOULDBLOCK || + errsv == EAGAIN)) +- continue; ++ { ++ if (!g_socket_condition_wait (socket, ++ G_IO_OUT, cancellable, error)) ++ return -1; ++ ++ continue; ++ } + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), +@@ -3942,11 +3944,6 @@ g_socket_send_message (GSocket *socket, + + while (1) + { +- if (socket->priv->blocking && +- !g_socket_condition_wait (socket, +- G_IO_OUT, cancellable, error)) +- return -1; +- + if (address) + result = WSASendTo (socket->priv->fd, + bufs, num_vectors, +@@ -3967,11 +3964,18 @@ g_socket_send_message (GSocket *socket, + continue; + + if (errsv == WSAEWOULDBLOCK) +- win32_unset_event_mask (socket, FD_WRITE); ++ { ++ win32_unset_event_mask (socket, FD_WRITE); + +- if (socket->priv->blocking && +- errsv == WSAEWOULDBLOCK) +- continue; ++ if (socket->priv->blocking) ++ { ++ if (!g_socket_condition_wait (socket, ++ G_IO_OUT, cancellable, error)) ++ return -1; ++ ++ continue; ++ } ++ } + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), +@@ -4634,11 +4638,6 @@ g_socket_receive_message (GSocket *socket, + /* do it */ + while (1) + { +- if (socket->priv->blocking && +- !g_socket_condition_wait (socket, +- G_IO_IN, cancellable, error)) +- return -1; +- + addrlen = sizeof addr; + if (address) + result = WSARecvFrom (socket->priv->fd, +@@ -4658,11 +4657,19 @@ g_socket_receive_message (GSocket *socket, + if (errsv == WSAEINTR) + continue; + +- win32_unset_event_mask (socket, FD_READ); ++ if (errsv == WSAEWOULDBLOCK) ++ { ++ win32_unset_event_mask (socket, FD_READ); + +- if (socket->priv->blocking && +- errsv == WSAEWOULDBLOCK) +- continue; ++ if (socket->priv->blocking) ++ { ++ if (!g_socket_condition_wait (socket, ++ G_IO_IN, cancellable, error)) ++ return -1; ++ ++ continue; ++ } ++ } + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), +-- +2.1.0 + diff --git a/mingw-w64-glib2/PKGBUILD b/mingw-w64-glib2/PKGBUILD index 104ae98b63..b571fad1d1 100644 --- a/mingw-w64-glib2/PKGBUILD +++ b/mingw-w64-glib2/PKGBUILD @@ -3,7 +3,7 @@ _realname=glib2 pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}" pkgver=2.42.1 -pkgrel=1 +pkgrel=2 url="http://www.gtk.org/" arch=('any') pkgdesc="Common C routines used by GTK+ 2.4 and other libs (mingw-w64)" @@ -25,7 +25,8 @@ source=("http://ftp.gnome.org/pub/GNOME/sources/glib/${pkgver%.*}/glib-$pkgver.t 0021-use-64bit-stat-for-localfile-size-calc.all.patch 0023-print-in-binary-more-for-testing.all.patch 0024-return-actually-written-data-in-printf.all.patch - 0026-define-HAVE_IF_NAMETOINDEX.patch) + 0026-define-HAVE_IF_NAMETOINDEX.patch + 0001-gsocket-block-when-errno-says-it-will-block.patch) md5sums=('89c4119e50e767d3532158605ee9121a' '98c7778b5e8a30dbcdb86bcd15f9c11d' '6eb9d56028ea3bbec3d053254a00a04b' @@ -36,7 +37,8 @@ md5sums=('89c4119e50e767d3532158605ee9121a' '952989e534235721d30b9ee3d89cc225' '217a997ede1b93ac06f96ed869b74378' '500f39baea98d98e4a2f877ad56f55a5' - 'de51a19cc5bfd0d54a59e9ac36cbafa2') + 'de51a19cc5bfd0d54a59e9ac36cbafa2' + 'c8942cf5035f97ade5ab9c757a210f01') prepare() { cd "$srcdir/glib-$pkgver" @@ -50,6 +52,7 @@ prepare() { patch -Np1 -i "$srcdir/0021-use-64bit-stat-for-localfile-size-calc.all.patch" patch -Np1 -i "$srcdir/0023-print-in-binary-more-for-testing.all.patch" patch -Np1 -i "$srcdir/0024-return-actually-written-data-in-printf.all.patch" + patch -Np1 -i "$srcdir/0001-gsocket-block-when-errno-says-it-will-block.patch" NOCONFIGURE=1 ./autogen.sh