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