|
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 logerr (struct audio_pt *pt, int err, const char *fmt, ...) |
|
10 { |
|
11 va_list ap; |
|
12 |
|
13 va_start (ap, fmt); |
|
14 AUD_vlog (pt->drv, fmt, ap); |
|
15 va_end (ap); |
|
16 |
|
17 AUD_log (NULL, "\n"); |
|
18 AUD_log (pt->drv, "Reason: %s\n", strerror (err)); |
|
19 } |
|
20 |
|
21 int audio_pt_init (struct audio_pt *p, void *(*func) (void *), |
|
22 void *opaque, const char *drv, const char *cap) |
|
23 { |
|
24 int err, err2; |
|
25 const char *efunc; |
|
26 |
|
27 p->drv = drv; |
|
28 |
|
29 err = pthread_mutex_init (&p->mutex, NULL); |
|
30 if (err) { |
|
31 efunc = "pthread_mutex_init"; |
|
32 goto err0; |
|
33 } |
|
34 |
|
35 err = pthread_cond_init (&p->cond, NULL); |
|
36 if (err) { |
|
37 efunc = "pthread_cond_init"; |
|
38 goto err1; |
|
39 } |
|
40 |
|
41 err = pthread_create (&p->thread, NULL, func, opaque); |
|
42 if (err) { |
|
43 efunc = "pthread_create"; |
|
44 goto err2; |
|
45 } |
|
46 |
|
47 return 0; |
|
48 |
|
49 err2: |
|
50 err2 = pthread_cond_destroy (&p->cond); |
|
51 if (err2) { |
|
52 logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC); |
|
53 } |
|
54 |
|
55 err1: |
|
56 err2 = pthread_mutex_destroy (&p->mutex); |
|
57 if (err2) { |
|
58 logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC); |
|
59 } |
|
60 |
|
61 err0: |
|
62 logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc); |
|
63 return -1; |
|
64 } |
|
65 |
|
66 int audio_pt_fini (struct audio_pt *p, const char *cap) |
|
67 { |
|
68 int err, ret = 0; |
|
69 |
|
70 err = pthread_cond_destroy (&p->cond); |
|
71 if (err) { |
|
72 logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC); |
|
73 ret = -1; |
|
74 } |
|
75 |
|
76 err = pthread_mutex_destroy (&p->mutex); |
|
77 if (err) { |
|
78 logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC); |
|
79 ret = -1; |
|
80 } |
|
81 return ret; |
|
82 } |
|
83 |
|
84 int audio_pt_lock (struct audio_pt *p, const char *cap) |
|
85 { |
|
86 int err; |
|
87 |
|
88 err = pthread_mutex_lock (&p->mutex); |
|
89 if (err) { |
|
90 logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC); |
|
91 return -1; |
|
92 } |
|
93 return 0; |
|
94 } |
|
95 |
|
96 int audio_pt_unlock (struct audio_pt *p, const char *cap) |
|
97 { |
|
98 int err; |
|
99 |
|
100 err = pthread_mutex_unlock (&p->mutex); |
|
101 if (err) { |
|
102 logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC); |
|
103 return -1; |
|
104 } |
|
105 return 0; |
|
106 } |
|
107 |
|
108 int audio_pt_wait (struct audio_pt *p, const char *cap) |
|
109 { |
|
110 int err; |
|
111 |
|
112 err = pthread_cond_wait (&p->cond, &p->mutex); |
|
113 if (err) { |
|
114 logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC); |
|
115 return -1; |
|
116 } |
|
117 return 0; |
|
118 } |
|
119 |
|
120 int audio_pt_unlock_and_signal (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 err = pthread_cond_signal (&p->cond); |
|
130 if (err) { |
|
131 logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC); |
|
132 return -1; |
|
133 } |
|
134 return 0; |
|
135 } |
|
136 |
|
137 int audio_pt_join (struct audio_pt *p, void **arg, const char *cap) |
|
138 { |
|
139 int err; |
|
140 void *ret; |
|
141 |
|
142 err = pthread_join (p->thread, &ret); |
|
143 if (err) { |
|
144 logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC); |
|
145 return -1; |
|
146 } |
|
147 *arg = ret; |
|
148 return 0; |
|
149 } |