Skip to content

Commit

Permalink
Do not use the default GMainContext
Browse files Browse the repository at this point in the history
Using the default GMainContext may cause deadlocks when mpv-mpris is
loaded in an mpv frontend that use GLib.
  • Loading branch information
gnome-mpv authored and hoyon committed Mar 30, 2023
1 parent b9b66af commit c760491
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions mpris.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,15 +988,17 @@ static void wakeup_handler(void *fd)
// Plugin entry point
int mpv_open_cplugin(mpv_handle *mpv)
{
GMainContext *ctx;
GMainLoop *loop;
UserData ud = {0};
GError *error = NULL;
GDBusNodeInfo *introspection_data = NULL;
int pipe[2];
guint mpv_pipe_source;
guint timeout_source;
GSource *mpv_pipe_source;
GSource *timeout_source;

loop = g_main_loop_new(NULL, FALSE);
ctx = g_main_context_new();
loop = g_main_loop_new(ctx, FALSE);

// Load introspection data and split into separate interfaces
introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
Expand All @@ -1015,13 +1017,15 @@ int mpv_open_cplugin(mpv_handle *mpv)
ud.changed_properties = g_hash_table_new(g_str_hash, g_str_equal);
ud.seek_expected = FALSE;

g_main_context_push_thread_default(ctx);
ud.bus_id = g_bus_own_name(G_BUS_TYPE_SESSION,
"org.mpris.MediaPlayer2.mpv",
G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE,
on_bus_acquired,
NULL,
on_name_lost,
&ud, NULL);
g_main_context_pop_thread_default(ctx);

// Receive event for property changes
mpv_observe_property(mpv, 0, "pause", MPV_FORMAT_FLAG);
Expand All @@ -1040,21 +1044,32 @@ int mpv_open_cplugin(mpv_handle *mpv)
}
fcntl(pipe[0], F_SETFL, O_NONBLOCK);
mpv_set_wakeup_callback(mpv, wakeup_handler, &pipe[1]);
mpv_pipe_source = g_unix_fd_add(pipe[0], G_IO_IN, event_handler, &ud);
mpv_pipe_source = g_unix_fd_source_new(pipe[0], G_IO_IN);
g_source_set_callback(mpv_pipe_source,
G_SOURCE_FUNC(event_handler),
&ud,
NULL);
g_source_attach(mpv_pipe_source, ctx);

// Emit any new property changes every 100ms
timeout_source = g_timeout_add(100, emit_property_changes, &ud);
timeout_source = g_timeout_source_new(100);
g_source_set_callback(timeout_source,
G_SOURCE_FUNC(emit_property_changes),
&ud,
NULL);
g_source_attach(timeout_source, ctx);

g_main_loop_run(loop);

g_source_remove(mpv_pipe_source);
g_source_remove(timeout_source);
g_source_unref(mpv_pipe_source);
g_source_unref(timeout_source);

g_dbus_connection_unregister_object(ud.connection, ud.root_interface_id);
g_dbus_connection_unregister_object(ud.connection, ud.player_interface_id);

g_bus_unown_name(ud.bus_id);
g_main_loop_unref(loop);
g_main_context_unref(ctx);
g_dbus_node_info_unref(introspection_data);

return 0;
Expand Down

0 comments on commit c760491

Please sign in to comment.