From 7756d37531ea48d1890363e8bda9b9872c771a9f Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 13 Feb 2009 18:03:14 +0100 Subject: pulsesink: Issue property change notification in streaming thread, rather than PA thread. pa_threaded_mainloop_lock() (a.o.) and by extension get_property should not be done from a PA thread, but the latter may occur as a result of a property change notification. Fixes #571204 (though current situation not ideal, e.g. post message rather than signal). --- ext/pulse/pulsesink.c | 14 ++++++++------ ext/pulse/pulsesink.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c index b167b43f..1d74aa23 100644 --- a/ext/pulse/pulsesink.c +++ b/ext/pulse/pulsesink.c @@ -269,6 +269,7 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass) pulsesink->operation_success = FALSE; pulsesink->did_reset = FALSE; pulsesink->in_write = FALSE; + pulsesink->notify = 0; pulsesink->mainloop = pa_threaded_mainloop_new (); g_assert (pulsesink->mainloop); @@ -621,13 +622,10 @@ gst_pulsesink_context_subscribe_cb (pa_context * c, /* Actually this event is also triggered when other properties of * the stream change that are unrelated to the volume. However it is * probably cheaper to signal the change here and check for the - * volume when the GObject property is read instead of querying it always. - * - * Lennart thinks this is a race because g_object_notify() is not - * thread safe and this function is run from a PA controlled - * thread. But folks on #gstreamer told me that was ok. */ + * volume when the GObject property is read instead of querying it always. */ - g_object_notify (G_OBJECT (pulsesink), "volume"); + /* inform streaming thread to notify */ + g_atomic_int_compare_and_exchange (&pulsesink->notify, 0, 1); } #endif @@ -876,6 +874,10 @@ gst_pulsesink_write (GstAudioSink * asink, gpointer data, guint length) GstPulseSink *pulsesink = GST_PULSESINK (asink); size_t sum = 0; + /* FIXME post message rather than using a signal (as mixer interface) */ + if (g_atomic_int_compare_and_exchange (&pulsesink->notify, 1, 0)) + g_object_notify (G_OBJECT (pulsesink), "volume"); + pa_threaded_mainloop_lock (pulsesink->mainloop); pulsesink->in_write = TRUE; diff --git a/ext/pulse/pulsesink.h b/ext/pulse/pulsesink.h index eb8d43d2..70fd8a65 100644 --- a/ext/pulse/pulsesink.h +++ b/ext/pulse/pulsesink.h @@ -68,6 +68,7 @@ struct _GstPulseSink gboolean operation_success; gboolean did_reset, in_write; + gint notify; }; struct _GstPulseSinkClass -- cgit