{
GActionGroup *action_group;
GDBusConnection *connection;
+ GMainContext *context;
gchar *object_path;
GHashTable *pending_changes;
GSource *pending_source;
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);
}
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);
* 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).
*
* 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
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);
}
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);
{
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;
}
test_dbus_threaded (void)
{
GSimpleActionGroup *group[10];
- GThread *call[10];
GThread *export[10];
static GActionEntry entries[] = {
{ "a", activate_action, NULL, NULL, NULL },
{
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]);