Home | History | Annotate | Download | only in audio
      1 #include "qemu-common.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 
      9 #include <signal.h>
     10 
     11 static void logerr (struct audio_pt *pt, int err, 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 
     23 int 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 
     91 int 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 
    109 int 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 
    121 int 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 
    133 int 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 
    145 int 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 
    162 int 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