Sorry, I almost forgot to reply to this... On Tue, 2012-12-25 at 21:13 +0100, Henrik /KaarPoSoft wrote: > Dear all, > > I have once again looked at this problem... > > > libcanberra contains this function: > > <code> > int driver_play(/* ... */) { > /* ... */ > if (name && cache_control != CA_CACHE_CONTROL_NEVER) { > /* ... */ > for (;;) { > /* ... */ > /* Let's try to play the sample */ > if (!(o = pa_context_play_sample_with_proplist(/* ... */) { > ret = translate_error(pa_context_errno(p->context)); > goto finish_locked; > } > > for (;;) { > pa_operation_state_t state = pa_operation_get_state(o); > > if (state == PA_OPERATION_DONE) { > canceled = FALSE; > break; > } else if (state == PA_OPERATION_CANCELED) { > canceled = TRUE; > break; > } > /* !!! We are hangining in the wait below !!! */ > pa_threaded_mainloop_wait(p->mainloop); > } > </code> > > The callback is defined as: > > <code> > static void play_sample_cb(pa_context *c, uint32_t idx, void *userdata) { > /* ... */ > pa_threaded_mainloop_signal(p->mainloop, FALSE); > } > </code> > > This seems to be modeled over > http://freedesktop.org/software/pulseaudio/doxygen/threaded_mainloop.html > > > So, two questions: > > > (1) > > It does not seem that play_sample_cb locks the mutex > p->mainloop->mutex > > I have not found any place in the code where the mutex is locked, > but then again I am no expert, and may have overlooked it ... > > QUESTION: > Should play_sample_cb (and the example for threaded_mainloop) > lock the mutex ??? > > It seems to me, that if the mutex is not locked, we risk that > the play_sample_cb might be called before pa_threaded_mainloop_wait, > and play_sample_cb is thus waking nobody, and pa_threaded_mainloop_wait > would then wait forever. I don't think the two threads can execute simultaneously, and therefore there's no such possibility that play_sample_cb() would get called between the calls to pa_context_play_sample_with_proplist() and and pa_threaded_mainloop_wait(). The reason why that can't happen is that pa_threaded_mainloop() locks the mutex immediately after returning from polling, so while driver_play() has the lock, the mainloop thread is blocked, and therefore play_sample_cb() can't get called before pa_threaded_mainloop_wait() is called. Also, pa_threaded_mainloop_wait() will wait until the mainloop thread has returned to polling. > (2) > > QUESTION: > Is it safe to call pa_operation_get_state(o) in the main loop??? > > I would think that other thread(s) might set the > operation_state, as I have not yet found the code which would > protect against this. Yes, it should be safe, since the operation state is queried when having the lock, and as explained above, having the lock implies that the mainloop thread is polling, and thus the operation state is stable. -- Tanu