qemu/audio/audio_pt_int.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include "qemu-common.h"
   3#include "audio.h"
   4
   5#define AUDIO_CAP "audio-pt"
   6
   7#include "audio_int.h"
   8#include "audio_pt_int.h"
   9
  10static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
  11                                       const char *fmt, ...)
  12{
  13    va_list ap;
  14
  15    va_start (ap, fmt);
  16    AUD_vlog (pt->drv, fmt, ap);
  17    va_end (ap);
  18
  19    AUD_log (NULL, "\n");
  20    AUD_log (pt->drv, "Reason: %s\n", strerror (err));
  21}
  22
  23int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
  24                   void *opaque, const char *drv, const char *cap)
  25{
  26    int err, err2;
  27    const char *efunc;
  28    sigset_t set, old_set;
  29
  30    p->drv = drv;
  31
  32    err = sigfillset (&set);
  33    if (err) {
  34        logerr (p, errno, "%s(%s): sigfillset failed", cap, AUDIO_FUNC);
  35        return -1;
  36    }
  37
  38    err = pthread_mutex_init (&p->mutex, NULL);
  39    if (err) {
  40        efunc = "pthread_mutex_init";
  41        goto err0;
  42    }
  43
  44    err = pthread_cond_init (&p->cond, NULL);
  45    if (err) {
  46        efunc = "pthread_cond_init";
  47        goto err1;
  48    }
  49
  50    err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
  51    if (err) {
  52        efunc = "pthread_sigmask";
  53        goto err2;
  54    }
  55
  56    err = pthread_create (&p->thread, NULL, func, opaque);
  57
  58    err2 = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
  59    if (err2) {
  60        logerr (p, err2, "%s(%s): pthread_sigmask (restore) failed",
  61                cap, AUDIO_FUNC);
  62        /* We have failed to restore original signal mask, all bets are off,
  63           so terminate the process */
  64        exit (EXIT_FAILURE);
  65    }
  66
  67    if (err) {
  68        efunc = "pthread_create";
  69        goto err2;
  70    }
  71
  72    return 0;
  73
  74 err2:
  75    err2 = pthread_cond_destroy (&p->cond);
  76    if (err2) {
  77        logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
  78    }
  79
  80 err1:
  81    err2 = pthread_mutex_destroy (&p->mutex);
  82    if (err2) {
  83        logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
  84    }
  85
  86 err0:
  87    logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
  88    return -1;
  89}
  90
  91int audio_pt_fini (struct audio_pt *p, const char *cap)
  92{
  93    int err, ret = 0;
  94
  95    err = pthread_cond_destroy (&p->cond);
  96    if (err) {
  97        logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
  98        ret = -1;
  99    }
 100
 101    err = pthread_mutex_destroy (&p->mutex);
 102    if (err) {
 103        logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
 104        ret = -1;
 105    }
 106    return ret;
 107}
 108
 109int audio_pt_lock (struct audio_pt *p, const char *cap)
 110{
 111    int err;
 112
 113    err = pthread_mutex_lock (&p->mutex);
 114    if (err) {
 115        logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
 116        return -1;
 117    }
 118    return 0;
 119}
 120
 121int audio_pt_unlock (struct audio_pt *p, const char *cap)
 122{
 123    int err;
 124
 125    err = pthread_mutex_unlock (&p->mutex);
 126    if (err) {
 127        logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
 128        return -1;
 129    }
 130    return 0;
 131}
 132
 133int audio_pt_wait (struct audio_pt *p, const char *cap)
 134{
 135    int err;
 136
 137    err = pthread_cond_wait (&p->cond, &p->mutex);
 138    if (err) {
 139        logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
 140        return -1;
 141    }
 142    return 0;
 143}
 144
 145int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
 146{
 147    int err;
 148
 149    err = pthread_mutex_unlock (&p->mutex);
 150    if (err) {
 151        logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
 152        return -1;
 153    }
 154    err = pthread_cond_signal (&p->cond);
 155    if (err) {
 156        logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
 157        return -1;
 158    }
 159    return 0;
 160}
 161
 162int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
 163{
 164    int err;
 165    void *ret;
 166
 167    err = pthread_join (p->thread, &ret);
 168    if (err) {
 169        logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
 170        return -1;
 171    }
 172    *arg = ret;
 173    return 0;
 174}
 175