mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-05 02:36:19 +01:00
Revert "GSocket: Fix race conditions on Win32 if multiple threads are waiting on conditions for the same socket"
This reverts commit 799f8dcd46
.
This patch seems to break applications that use GTask specific
operations with GSocket. We will need to investigate a bit more
on this issue but for now we revert it and leave it for the
next major release.
This commit is contained in:
parent
51e852e5d0
commit
f9d95de490
@ -252,14 +252,11 @@ struct _GSocketPrivate
|
||||
guint connect_pending : 1;
|
||||
#ifdef G_OS_WIN32
|
||||
WSAEVENT event;
|
||||
gboolean waiting;
|
||||
DWORD waiting_result;
|
||||
int current_events;
|
||||
int current_errors;
|
||||
int selected_events;
|
||||
GList *requested_conditions; /* list of requested GIOCondition * */
|
||||
GMutex win32_source_lock;
|
||||
GCond win32_source_cond;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
@ -346,10 +343,8 @@ socket_strerror (int err)
|
||||
static void
|
||||
_win32_unset_event_mask (GSocket *socket, int mask)
|
||||
{
|
||||
g_mutex_lock (&socket->priv->win32_source_lock);
|
||||
socket->priv->current_events &= ~mask;
|
||||
socket->priv->current_errors &= ~mask;
|
||||
g_mutex_unlock (&socket->priv->win32_source_lock);
|
||||
}
|
||||
#else
|
||||
#define win32_unset_event_mask(_socket, _mask)
|
||||
@ -847,7 +842,6 @@ g_socket_finalize (GObject *object)
|
||||
|
||||
g_assert (socket->priv->requested_conditions == NULL);
|
||||
g_mutex_clear (&socket->priv->win32_source_lock);
|
||||
g_cond_clear (&socket->priv->win32_source_cond);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < RECV_ADDR_CACHE_SIZE; i++)
|
||||
@ -1075,7 +1069,6 @@ g_socket_init (GSocket *socket)
|
||||
#ifdef G_OS_WIN32
|
||||
socket->priv->event = WSA_INVALID_EVENT;
|
||||
g_mutex_init (&socket->priv->win32_source_lock);
|
||||
g_cond_init (&socket->priv->win32_source_cond);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2459,8 +2452,6 @@ g_socket_accept (GSocket *socket,
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_ACCEPT);
|
||||
|
||||
if ((ret = accept (socket->priv->fd, NULL, 0)) < 0)
|
||||
{
|
||||
int errsv = get_socket_errno ();
|
||||
@ -2475,6 +2466,8 @@ g_socket_accept (GSocket *socket,
|
||||
errsv == EAGAIN)
|
||||
#endif
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_ACCEPT);
|
||||
|
||||
if (socket->priv->blocking)
|
||||
{
|
||||
if (!g_socket_condition_wait (socket,
|
||||
@ -2491,6 +2484,8 @@ g_socket_accept (GSocket *socket,
|
||||
break;
|
||||
}
|
||||
|
||||
win32_unset_event_mask (socket, FD_ACCEPT);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
{
|
||||
/* The socket inherits the accepting sockets event mask and even object,
|
||||
@ -2579,8 +2574,6 @@ g_socket_connect (GSocket *socket,
|
||||
|
||||
while (1)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_CONNECT);
|
||||
|
||||
if (connect (socket->priv->fd, (struct sockaddr *) &buffer,
|
||||
g_socket_address_get_native_size (address)) < 0)
|
||||
{
|
||||
@ -2595,6 +2588,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))
|
||||
@ -2620,6 +2615,8 @@ g_socket_connect (GSocket *socket,
|
||||
break;
|
||||
}
|
||||
|
||||
win32_unset_event_mask (socket, FD_CONNECT);
|
||||
|
||||
socket->priv->connected_read = TRUE;
|
||||
socket->priv->connected_write = TRUE;
|
||||
|
||||
@ -2799,8 +2796,6 @@ g_socket_receive_with_timeout (GSocket *socket,
|
||||
|
||||
while (1)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
|
||||
if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0)
|
||||
{
|
||||
int errsv = get_socket_errno ();
|
||||
@ -2815,6 +2810,8 @@ g_socket_receive_with_timeout (GSocket *socket,
|
||||
errsv == EAGAIN)
|
||||
#endif
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
|
||||
if (timeout != 0)
|
||||
{
|
||||
if (!block_on_timeout (socket, G_IO_IN, timeout, start_time,
|
||||
@ -2825,10 +2822,14 @@ g_socket_receive_with_timeout (GSocket *socket,
|
||||
}
|
||||
}
|
||||
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
|
||||
socket_set_error_lazy (error, errsv, _("Error receiving data: %s"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2994,8 +2995,6 @@ g_socket_send_with_timeout (GSocket *socket,
|
||||
|
||||
while (1)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_WRITE);
|
||||
|
||||
if ((ret = send (socket->priv->fd, buffer, size, G_SOCKET_DEFAULT_SEND_FLAGS)) < 0)
|
||||
{
|
||||
int errsv = get_socket_errno ();
|
||||
@ -3010,6 +3009,8 @@ g_socket_send_with_timeout (GSocket *socket,
|
||||
errsv == EAGAIN)
|
||||
#endif
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_WRITE);
|
||||
|
||||
if (timeout != 0)
|
||||
{
|
||||
if (!block_on_timeout (socket, G_IO_OUT, timeout, start_time,
|
||||
@ -3424,7 +3425,7 @@ remove_condition_watch (GSocket *socket,
|
||||
}
|
||||
|
||||
static GIOCondition
|
||||
update_condition_unlocked (GSocket *socket)
|
||||
update_condition (GSocket *socket)
|
||||
{
|
||||
WSANETWORKEVENTS events;
|
||||
GIOCondition condition;
|
||||
@ -3491,16 +3492,6 @@ update_condition_unlocked (GSocket *socket)
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
static GIOCondition
|
||||
update_condition (GSocket *socket)
|
||||
{
|
||||
GIOCondition res;
|
||||
g_mutex_lock (&socket->priv->win32_source_lock);
|
||||
res = update_condition_unlocked (socket);
|
||||
g_mutex_unlock (&socket->priv->win32_source_lock);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
@ -3896,44 +3887,11 @@ g_socket_condition_timed_wait (GSocket *socket,
|
||||
if (timeout == -1)
|
||||
timeout = WSA_INFINITE;
|
||||
|
||||
g_mutex_lock (&socket->priv->win32_source_lock);
|
||||
current_condition = update_condition_unlocked (socket);
|
||||
current_condition = update_condition (socket);
|
||||
while ((condition & current_condition) == 0)
|
||||
{
|
||||
if (!socket->priv->waiting)
|
||||
{
|
||||
socket->priv->waiting = TRUE;
|
||||
socket->priv->waiting_result = 0;
|
||||
g_mutex_unlock (&socket->priv->win32_source_lock);
|
||||
|
||||
res = WSAWaitForMultipleEvents (num_events, events, FALSE, timeout, FALSE);
|
||||
|
||||
g_mutex_lock (&socket->priv->win32_source_lock);
|
||||
socket->priv->waiting = FALSE;
|
||||
socket->priv->waiting_result = res;
|
||||
g_cond_broadcast (&socket->priv->win32_source_cond);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeout != WSA_INFINITE)
|
||||
{
|
||||
if (!g_cond_wait_until (&socket->priv->win32_source_cond, &socket->priv->win32_source_lock, timeout))
|
||||
{
|
||||
res = WSA_WAIT_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = socket->priv->waiting_result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_cond_wait (&socket->priv->win32_source_cond, &socket->priv->win32_source_lock);
|
||||
res = socket->priv->waiting_result;
|
||||
}
|
||||
}
|
||||
|
||||
res = WSAWaitForMultipleEvents (num_events, events,
|
||||
FALSE, timeout, FALSE);
|
||||
if (res == WSA_WAIT_FAILED)
|
||||
{
|
||||
int errsv = get_socket_errno ();
|
||||
@ -3954,7 +3912,7 @@ g_socket_condition_timed_wait (GSocket *socket,
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
break;
|
||||
|
||||
current_condition = update_condition_unlocked (socket);
|
||||
current_condition = update_condition (socket);
|
||||
|
||||
if (timeout != WSA_INFINITE)
|
||||
{
|
||||
@ -3963,7 +3921,6 @@ g_socket_condition_timed_wait (GSocket *socket,
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
g_mutex_unlock (&socket->priv->win32_source_lock);
|
||||
remove_condition_watch (socket, &condition);
|
||||
if (num_events > 1)
|
||||
g_cancellable_release_fd (cancellable);
|
||||
@ -4461,8 +4418,6 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
||||
|
||||
while (1)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_WRITE);
|
||||
|
||||
if (address)
|
||||
result = WSASendTo (socket->priv->fd,
|
||||
bufs, num_vectors,
|
||||
@ -4484,6 +4439,8 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
||||
|
||||
if (errsv == WSAEWOULDBLOCK)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_WRITE);
|
||||
|
||||
if (timeout != 0)
|
||||
{
|
||||
if (!block_on_timeout (socket, G_IO_OUT, timeout,
|
||||
@ -4931,8 +4888,6 @@ g_socket_receive_message_with_timeout (GSocket *socket,
|
||||
/* do it */
|
||||
while (1)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
|
||||
addrlen = sizeof addr;
|
||||
if (address)
|
||||
result = WSARecvFrom (socket->priv->fd,
|
||||
@ -4954,6 +4909,8 @@ g_socket_receive_message_with_timeout (GSocket *socket,
|
||||
|
||||
if (errsv == WSAEWOULDBLOCK)
|
||||
{
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
|
||||
if (timeout != 0)
|
||||
{
|
||||
if (!block_on_timeout (socket, G_IO_IN, timeout,
|
||||
@ -4967,6 +4924,7 @@ g_socket_receive_message_with_timeout (GSocket *socket,
|
||||
socket_set_error_lazy (error, errsv, _("Error receiving message: %s"));
|
||||
return -1;
|
||||
}
|
||||
win32_unset_event_mask (socket, FD_READ);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user