Merge branch 'gdbus-peer-fix-multiple-returns' into 'master'

gsocketlistener: Fix multiple returns of GTask when accepting sockets

See merge request GNOME/glib!645
This commit is contained in:
Philip Withnall 2019-02-11 00:48:32 +00:00
commit d3523dfd9a

View File

@ -773,6 +773,19 @@ g_socket_listener_accept (GSocketListener *listener,
return connection; return connection;
} }
typedef struct
{
GList *sources; /* (element-type GSource) */
gboolean returned_yet;
} AcceptSocketAsyncData;
static void
accept_socket_async_data_free (AcceptSocketAsyncData *data)
{
free_sources (data->sources);
g_free (data);
}
static gboolean static gboolean
accept_ready (GSocket *accept_socket, accept_ready (GSocket *accept_socket,
GIOCondition condition, GIOCondition condition,
@ -782,6 +795,12 @@ accept_ready (GSocket *accept_socket,
GError *error = NULL; GError *error = NULL;
GSocket *socket; GSocket *socket;
GObject *source_object; GObject *source_object;
AcceptSocketAsyncData *data = g_task_get_task_data (task);
/* Dont call g_task_return_*() multiple times if we have multiple incoming
* connections in the same #GMainContext iteration. */
if (data->returned_yet)
return G_SOURCE_REMOVE;
socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error); socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
if (socket) if (socket)
@ -798,8 +817,10 @@ accept_ready (GSocket *accept_socket,
g_task_return_error (task, error); g_task_return_error (task, error);
} }
data->returned_yet = TRUE;
g_object_unref (task); g_object_unref (task);
return FALSE;
return G_SOURCE_REMOVE;
} }
/** /**
@ -824,8 +845,8 @@ g_socket_listener_accept_socket_async (GSocketListener *listener,
gpointer user_data) gpointer user_data)
{ {
GTask *task; GTask *task;
GList *sources;
GError *error = NULL; GError *error = NULL;
AcceptSocketAsyncData *data = NULL;
task = g_task_new (listener, cancellable, callback, user_data); task = g_task_new (listener, cancellable, callback, user_data);
g_task_set_source_tag (task, g_socket_listener_accept_socket_async); g_task_set_source_tag (task, g_socket_listener_accept_socket_async);
@ -837,12 +858,15 @@ g_socket_listener_accept_socket_async (GSocketListener *listener,
return; return;
} }
sources = add_sources (listener, data = g_new0 (AcceptSocketAsyncData, 1);
data->returned_yet = FALSE;
data->sources = add_sources (listener,
accept_ready, accept_ready,
task, task,
cancellable, cancellable,
g_main_context_get_thread_default ()); g_main_context_get_thread_default ());
g_task_set_task_data (task, sources, (GDestroyNotify) free_sources); g_task_set_task_data (task, g_steal_pointer (&data),
(GDestroyNotify) accept_socket_async_data_free);
} }
/** /**