glib2: fix hang on gsocket
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
From 177ff38e103a76b7cd153c4c8014159eb6a9eb60 Mon Sep 17 00:00:00 2001
|
||||
From: Ignacio Casal Quinteiro <icq@gnome.org>
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user