[pulseaudio-discuss] gnome-shell hangs, waiting for pulse-audio

Tanu Kaskinen tanuk at iki.fi
Thu Jan 3 05:19:31 PST 2013


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



More information about the pulseaudio-discuss mailing list