mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 15:33:39 +02:00
GDBusConnection: delegate to the worker to close the stream
We can't safely close the output part of the I/O stream until any pending write or flush has been completed. In the worst case, this could lead to an assertion failure in the worker (when the close wins the race) or not closing the stream at all (when the write wins the race). Bug: https://bugzilla.gnome.org/show_bug.cgi?id=651268 Bug-NB: NB#271520 Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk> Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
committed by
David Zeuthen
parent
a8f75f21b4
commit
8097e2de85
@@ -513,12 +513,6 @@ g_dbus_connection_finalize (GObject *object)
|
||||
|
||||
if (connection->stream != NULL)
|
||||
{
|
||||
/* We don't really care if closing the stream succeeds or not */
|
||||
g_io_stream_close_async (connection->stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL, /* GCancellable */
|
||||
NULL, /* GAsyncReadyCallback */
|
||||
NULL); /* userdata */
|
||||
g_object_unref (connection->stream);
|
||||
connection->stream = NULL;
|
||||
}
|
||||
@@ -1225,20 +1219,6 @@ set_closed_unlocked (GDBusConnection *connection,
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
close_in_thread_func (GSimpleAsyncResult *res,
|
||||
GObject *object,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
if (!g_dbus_connection_close_sync (G_DBUS_CONNECTION (object),
|
||||
cancellable,
|
||||
&error))
|
||||
g_simple_async_result_take_error (res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_dbus_connection_close:
|
||||
* @connection: A #GDBusConnection.
|
||||
@@ -1288,10 +1268,7 @@ g_dbus_connection_close (GDBusConnection *connection,
|
||||
callback,
|
||||
user_data,
|
||||
g_dbus_connection_close);
|
||||
g_simple_async_result_run_in_thread (simple,
|
||||
close_in_thread_func,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable);
|
||||
_g_dbus_worker_close (connection->worker, cancellable, simple);
|
||||
g_object_unref (simple);
|
||||
}
|
||||
|
||||
@@ -1332,6 +1309,22 @@ g_dbus_connection_close_finish (GDBusConnection *connection,
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GMainLoop *loop;
|
||||
GAsyncResult *result;
|
||||
} SyncCloseData;
|
||||
|
||||
static void
|
||||
sync_close_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
SyncCloseData *data = user_data;
|
||||
|
||||
data->result = g_object_ref (res);
|
||||
g_main_loop_quit (data->loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_dbus_connection_close_sync:
|
||||
* @connection: A #GDBusConnection.
|
||||
@@ -1362,11 +1355,24 @@ g_dbus_connection_close_sync (GDBusConnection *connection,
|
||||
CONNECTION_LOCK (connection);
|
||||
if (!connection->closed)
|
||||
{
|
||||
ret = g_io_stream_close (connection->stream,
|
||||
cancellable,
|
||||
error);
|
||||
if (ret)
|
||||
set_closed_unlocked (connection, FALSE, NULL);
|
||||
GMainContext *context;
|
||||
SyncCloseData data;
|
||||
|
||||
context = g_main_context_new ();
|
||||
g_main_context_push_thread_default (context);
|
||||
data.loop = g_main_loop_new (context, TRUE);
|
||||
data.result = NULL;
|
||||
|
||||
CONNECTION_UNLOCK (connection);
|
||||
g_dbus_connection_close (connection, cancellable, sync_close_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
ret = g_dbus_connection_close_finish (connection, data.result, error);
|
||||
CONNECTION_LOCK (connection);
|
||||
|
||||
g_object_unref (data.result);
|
||||
g_main_loop_unref (data.loop);
|
||||
g_main_context_pop_thread_default (context);
|
||||
g_main_context_unref (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user