[glib] socket: Don't poll the socket fd after close
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] socket: Don't poll the socket fd after close
- Date: Tue, 24 Oct 2017 14:02:17 +0000 (UTC)
commit f99045fd03fecacc5f7e1728086091a3538cd761
Author: Michael Catanzaro <mcatanzaro igalia com>
Date: Fri Oct 20 21:18:46 2017 -0500
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
gio/gsocket.c | 41 ++++++++++++++++++++++++++++++++---------
1 files changed, 32 insertions(+), 9 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index c4147fb..42c73e6 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]