These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / audio / audio_pt_int.c
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
10 static 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
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 }