aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/gtk-vlc-player/gtk-vlc-player.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/lib/gtk-vlc-player/gtk-vlc-player.c b/lib/gtk-vlc-player/gtk-vlc-player.c
index 03179ed..97a7115 100644
--- a/lib/gtk-vlc-player/gtk-vlc-player.c
+++ b/lib/gtk-vlc-player/gtk-vlc-player.c
@@ -38,6 +38,7 @@
#include <glib/gprintf.h>
#include <gtk/gtk.h>
+#include <gdk/gdk.h>
#ifdef G_OS_WIN32
#include <gdk/gdkwin32.h>
#else
@@ -57,6 +58,9 @@ static void gtk_vlc_player_init(GtkVlcPlayer *klass);
static void gtk_vlc_player_dispose(GObject *gobject);
static void gtk_vlc_player_finalize(GObject *gobject);
+static inline void maybe_lock_gdk(void);
+static inline void maybe_unlock_gdk(void);
+
#ifdef G_OS_WIN32
static BOOL CALLBACK enumerate_vlc_windows_cb(HWND hWndvlc, LPARAM lParam);
static gboolean poll_vlc_event_window_cb(gpointer data);
@@ -308,6 +312,34 @@ gtk_vlc_player_finalize(GObject *gobject)
G_OBJECT_CLASS(gtk_vlc_player_parent_class)->finalize(gobject);
}
+/**
+ * @brief Locks GDK mutex if necessary.
+ *
+ * When GTK+ functions are invoked from another than the main
+ * thread (the one with the \e gtk_main() event loop),
+ * \e gdk_threads_enter() must be called.
+ * This auxiliary function is for callers (like VLC callbacks) that
+ * may or may not be invoked from the main event loop to avoid dead locks.
+ */
+static inline void
+maybe_lock_gdk(void)
+{
+ if (!g_main_context_is_owner(g_main_context_default()))
+ gdk_threads_enter();
+}
+
+/**
+ * @brief Unlocks GDK mutex if necessary.
+ *
+ * @see maybe_lock_gdk
+ */
+static inline void
+maybe_unlock_gdk(void)
+{
+ if (!g_main_context_is_owner(g_main_context_default()))
+ gdk_threads_leave();
+}
+
#ifdef G_OS_WIN32
static BOOL CALLBACK
@@ -478,11 +510,11 @@ vlc_time_changed(const struct libvlc_event_t *event, void *user_data)
{
assert(event->type == libvlc_MediaPlayerTimeChanged);
- /* VLC callbacks are invoked from another thread! */
- gdk_threads_enter();
+ /* VLC callbacks may be invoked from another thread! */
+ maybe_lock_gdk();
update_time(GTK_VLC_PLAYER(user_data),
(gint64)event->u.media_player_time_changed.new_time);
- gdk_threads_leave();
+ maybe_unlock_gdk();
}
static void
@@ -490,11 +522,11 @@ vlc_length_changed(const struct libvlc_event_t *event, void *user_data)
{
assert(event->type == libvlc_MediaPlayerLengthChanged);
- /* VLC callbacks are invoked from another thread! */
- gdk_threads_enter();
+ /* VLC callbacks may be invoked from another thread! */
+ maybe_lock_gdk();
update_length(GTK_VLC_PLAYER(user_data),
(gint64)event->u.media_player_length_changed.new_length);
- gdk_threads_leave();
+ maybe_unlock_gdk();
}
static void