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