Add qemu 2.4.0
[kvmfornfv.git] / qemu / audio / audio_pt_int.c
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 static 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
22 int 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, AUDIO_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, AUDIO_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, AUDIO_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, AUDIO_FUNC);
83     }
84
85  err0:
86     logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
87     return -1;
88 }
89
90 int 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, AUDIO_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, AUDIO_FUNC);
103         ret = -1;
104     }
105     return ret;
106 }
107
108 int 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, AUDIO_FUNC);
115         return -1;
116     }
117     return 0;
118 }
119
120 int 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, AUDIO_FUNC);
127         return -1;
128     }
129     return 0;
130 }
131
132 int 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, AUDIO_FUNC);
139         return -1;
140     }
141     return 0;
142 }
143
144 int 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, AUDIO_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, AUDIO_FUNC);
156         return -1;
157     }
158     return 0;
159 }
160
161 int 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, AUDIO_FUNC);
169         return -1;
170     }
171     *arg = ret;
172     return 0;
173 }