Max Kellermann <[EMAIL PROTECTED]> wrote:
> Max Kellermann (15):
>       output: one thread per audio output

Hi Max,

Neither notify nor condition are optimal for the one thread per audio
output stuff.

Instead, use one global condition variable and multiple mutexes (one mutex
per output) and pthread_cond_broadcast().


In each output thread:

        pthread_mutex_lock(&ao->mutex); /* start of thread */
        while (1) {
                ...
                /*
     * ao->mutex gets unlocked here, multiple threads can wait
     * on the same condition variable (with a different mutex)
     * at once.  A single call to pthread_cond_broadcast() will
     * wake them all up
     */
                pthread_cond_wait(&global_ao_cond, &ao->mutex);
                ...
        }
        pthread_mutex_unlock(&ao->mutex); /* end of thread */

playAudio()/flushAudioBuffer() will then call
pthread_cond_broadcast(&global_ao_cond).   I would do this after
verifying that at least of the ao->mutex-es is unlocked; indicating that
there's at least one playable output.


The only drawback to my approach is that output-specific calls to
enable/disable devices will get hit by a global wakeup, but these are
very uncommon compared to the number of calls that go to all outputs.

Currently, it seems that playAudio() still waits until all the outputs
have played.  This seems wrong to me.  If some outputs are blocking
others from completing, it should be skipped over (and drop audio) to
not affect other outputs.

The main reason for using per-output threads is because we cannot (and
should not) rely on outputs being fully non-blocking (indeed, the main
reason for using threads anywhere is because non-blocking APIs don't
exist or are incomplete/broken).  Multiprocessing advantages are small
and not necessary for the vast majority of users.


A note about notify:

  The pending flag in notify has always bugged me as it's totally
  unnecessary.  pthread_cond_wait() atomically unlocks the mutex when it
  is called and starts waiting.  This is for allowing a signalling
  thread to check to see if the waiter is signal-able.   So attempting
  to lock the mutex that is passed to pthread_cond_wait is already
  enough to know if there's a thread waiting on that condition variable.


-- 
Eric Wong

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team

Reply via email to