mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 07:26:15 +01:00
socket: Don't poll the socket fd after close
This prevents polling on file descriptors that are no longer in use or have been reused for something else. Based on a patch by Mikhail Zabaluev https://bugzilla.gnome.org/show_bug.cgi?id=723655
This commit is contained in:
parent
9023fa350d
commit
f99045fd03
@ -3744,24 +3744,38 @@ typedef struct {
|
||||
GIOCondition condition;
|
||||
} GSocketSource;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
static gboolean
|
||||
socket_source_prepare_win32 (GSource *source,
|
||||
gint *timeout)
|
||||
socket_source_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
{
|
||||
GSocketSource *socket_source = (GSocketSource *)source;
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
if ((socket_source->pollfd.revents & G_IO_NVAL) != 0)
|
||||
return TRUE;
|
||||
|
||||
if (g_socket_is_closed (socket_source->socket))
|
||||
{
|
||||
g_source_remove_poll (source, &socket_source->pollfd);
|
||||
socket_source->pollfd.revents = G_IO_NVAL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return (update_condition (socket_source->socket) & socket_source->condition) != 0;
|
||||
#else
|
||||
return g_socket_is_closed (socket_source->socket) && socket_source->fd_tag != NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
static gboolean
|
||||
socket_source_check_win32 (GSource *source)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
return socket_source_prepare_win32 (source, &timeout);
|
||||
return socket_source_prepare (source, &timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3780,11 +3794,20 @@ socket_source_dispatch (GSource *source,
|
||||
#ifdef G_OS_WIN32
|
||||
events = update_condition (socket_source->socket);
|
||||
#else
|
||||
events = g_source_query_unix_fd (source, socket_source->fd_tag);
|
||||
if (g_socket_is_closed (socket_source->socket))
|
||||
{
|
||||
socket_source->fd_tag = NULL;
|
||||
events = G_IO_NVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
events = g_source_query_unix_fd (source, socket_source->fd_tag);
|
||||
}
|
||||
#endif
|
||||
|
||||
timeout = g_source_get_ready_time (source);
|
||||
if (timeout >= 0 && timeout < g_source_get_time (source))
|
||||
if (timeout >= 0 && timeout < g_source_get_time (source) &&
|
||||
!g_socket_is_closed (socket_source->socket))
|
||||
{
|
||||
socket->priv->timed_out = TRUE;
|
||||
events |= (G_IO_IN | G_IO_OUT);
|
||||
@ -3792,7 +3815,7 @@ socket_source_dispatch (GSource *source,
|
||||
|
||||
ret = (*func) (socket, events & socket_source->condition, user_data);
|
||||
|
||||
if (socket->priv->timeout)
|
||||
if (socket->priv->timeout && !g_socket_is_closed (socket_source->socket))
|
||||
g_source_set_ready_time (source, g_get_monotonic_time () + socket->priv->timeout * 1000000);
|
||||
else
|
||||
g_source_set_ready_time (source, -1);
|
||||
@ -3845,11 +3868,11 @@ socket_source_closure_callback (GSocket *socket,
|
||||
|
||||
static GSourceFuncs socket_source_funcs =
|
||||
{
|
||||
socket_source_prepare,
|
||||
#ifdef G_OS_WIN32
|
||||
socket_source_prepare_win32,
|
||||
socket_source_check_win32,
|
||||
#else
|
||||
NULL, NULL, /* check, prepare */
|
||||
NULL,
|
||||
#endif
|
||||
socket_source_dispatch,
|
||||
socket_source_finalize,
|
||||
|
Loading…
Reference in New Issue
Block a user