mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 05:56:14 +01:00
action exporter: clarify threading situation
Exporting can only be done relative to a particular given main context and all interaction with the action group must be on that same context. Fix up the implementation so that the user can specify that context with the normal (thread default) mechanism and document the limitation on the API. Adjust the testcase to adhere to the documentation limitations. It passes now.
This commit is contained in:
parent
7af08e1fc0
commit
14900d37f4
@ -216,6 +216,7 @@ typedef struct
|
||||
{
|
||||
GActionGroup *action_group;
|
||||
GDBusConnection *connection;
|
||||
GMainContext *context;
|
||||
gchar *object_path;
|
||||
GHashTable *pending_changes;
|
||||
GSource *pending_source;
|
||||
@ -329,7 +330,7 @@ g_action_group_exporter_set_events (GActionGroupExporter *exporter,
|
||||
source = g_idle_source_new ();
|
||||
exporter->pending_source = source;
|
||||
g_source_set_callback (source, g_action_group_exporter_dispatch_events, exporter, NULL);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_attach (source, exporter->context);
|
||||
g_source_unref (source);
|
||||
}
|
||||
|
||||
@ -566,6 +567,7 @@ g_action_group_exporter_free (gpointer user_data)
|
||||
if (exporter->pending_source)
|
||||
g_source_destroy (exporter->pending_source);
|
||||
|
||||
g_main_context_unref (exporter->context);
|
||||
g_object_unref (exporter->connection);
|
||||
g_object_unref (exporter->action_group);
|
||||
g_free (exporter->object_path);
|
||||
@ -585,7 +587,7 @@ g_action_group_exporter_free (gpointer user_data)
|
||||
* The implemented D-Bus API should be considered private. It is
|
||||
* subject to change in the future.
|
||||
*
|
||||
* A given * object path can only have one action group exported on it.
|
||||
* A given object path can only have one action group exported on it.
|
||||
* If this constraint is violated, the export will fail and 0 will be
|
||||
* returned (with @error set accordingly).
|
||||
*
|
||||
@ -593,6 +595,15 @@ g_action_group_exporter_free (gpointer user_data)
|
||||
* g_dbus_connection_unexport_action_group() with the return value of
|
||||
* this function.
|
||||
*
|
||||
* The thread default main context is taken at the time of this call.
|
||||
* All incoming action activations and state change requests are
|
||||
* reported from this context. Any changes on the action group that
|
||||
* cause it to emit signals must also come from this same context.
|
||||
* Since incoming action activations and state change requests are
|
||||
* rather likely to cause changes on the action group, this effectively
|
||||
* limits a given action group to being exported from only one main
|
||||
* context.
|
||||
*
|
||||
* Returns: the ID of the export (never zero), or 0 in case of failure
|
||||
*
|
||||
* Since: 2.32
|
||||
@ -633,6 +644,7 @@ g_dbus_connection_export_action_group (GDBusConnection *connection,
|
||||
return 0;
|
||||
}
|
||||
|
||||
exporter->context = g_main_context_ref_thread_default ();
|
||||
exporter->pending_changes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
exporter->pending_source = NULL;
|
||||
exporter->action_group = g_object_ref (action_group);
|
||||
|
@ -624,33 +624,22 @@ test_dbus_export (void)
|
||||
g_object_unref (bus);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
do_activate (gpointer data)
|
||||
{
|
||||
GSimpleActionGroup *group = data;
|
||||
gint i;
|
||||
GAction *action;
|
||||
|
||||
for (i = 0; i < 1000000; i++)
|
||||
{
|
||||
action = g_simple_action_group_lookup (group, "a");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
!g_action_get_enabled (action));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
do_export (gpointer data)
|
||||
{
|
||||
GActionGroup *group = data;
|
||||
GMainContext *ctx;
|
||||
gint i;
|
||||
GError *error = NULL;
|
||||
guint id;
|
||||
GDBusConnection *bus;
|
||||
GAction *action;
|
||||
gchar *path;
|
||||
|
||||
ctx = g_main_context_new ();
|
||||
|
||||
g_main_context_push_thread_default (ctx);
|
||||
|
||||
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||
path = g_strdup_printf("/%p", data);
|
||||
|
||||
@ -658,12 +647,23 @@ do_export (gpointer data)
|
||||
{
|
||||
id = g_dbus_connection_export_action_group (bus, path, G_ACTION_GROUP (group), &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
action = g_simple_action_group_lookup (G_SIMPLE_ACTION_GROUP (group), "a");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
!g_action_get_enabled (action));
|
||||
|
||||
g_dbus_connection_unexport_action_group (bus, id);
|
||||
|
||||
while (g_main_context_iteration (ctx, FALSE));
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
g_object_unref (bus);
|
||||
|
||||
g_main_context_pop_thread_default (ctx);
|
||||
|
||||
g_main_context_unref (ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -671,7 +671,6 @@ static void
|
||||
test_dbus_threaded (void)
|
||||
{
|
||||
GSimpleActionGroup *group[10];
|
||||
GThread *call[10];
|
||||
GThread *export[10];
|
||||
static GActionEntry entries[] = {
|
||||
{ "a", activate_action, NULL, NULL, NULL },
|
||||
@ -683,15 +682,11 @@ test_dbus_threaded (void)
|
||||
{
|
||||
group[i] = g_simple_action_group_new ();
|
||||
g_simple_action_group_add_entries (group[i], entries, G_N_ELEMENTS (entries), NULL);
|
||||
call[i] = g_thread_new ("call", do_activate, group[i]);
|
||||
export[i] = g_thread_new ("export", do_export, group[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
g_thread_join (call[i]);
|
||||
g_thread_join (export[i]);
|
||||
}
|
||||
g_thread_join (export[i]);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
g_object_unref (group[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user