Statistics
| Branch: | Revision:

root / audio / audio_pt_int.c @ 9bf0960a

History | View | Annotate | Download (3.9 kB)

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
}