Statistics
| Branch: | Revision:

root / audio / audio_pt_int.c @ 43a2b339

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
#include <signal.h>
10

    
11
static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
12
                                       const char *fmt, ...)
13
{
14
    va_list ap;
15

    
16
    va_start (ap, fmt);
17
    AUD_vlog (pt->drv, fmt, ap);
18
    va_end (ap);
19

    
20
    AUD_log (NULL, "\n");
21
    AUD_log (pt->drv, "Reason: %s\n", strerror (err));
22
}
23

    
24
int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
25
                   void *opaque, const char *drv, const char *cap)
26
{
27
    int err, err2;
28
    const char *efunc;
29
    sigset_t set, old_set;
30

    
31
    p->drv = drv;
32

    
33
    err = sigfillset (&set);
34
    if (err) {
35
        logerr (p, errno, "%s(%s): sigfillset failed", cap, AUDIO_FUNC);
36
        return -1;
37
    }
38

    
39
    err = pthread_mutex_init (&p->mutex, NULL);
40
    if (err) {
41
        efunc = "pthread_mutex_init";
42
        goto err0;
43
    }
44

    
45
    err = pthread_cond_init (&p->cond, NULL);
46
    if (err) {
47
        efunc = "pthread_cond_init";
48
        goto err1;
49
    }
50

    
51
    err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
52
    if (err) {
53
        efunc = "pthread_sigmask";
54
        goto err2;
55
    }
56

    
57
    err = pthread_create (&p->thread, NULL, func, opaque);
58

    
59
    err2 = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
60
    if (err2) {
61
        logerr (p, err2, "%s(%s): pthread_sigmask (restore) failed",
62
                cap, AUDIO_FUNC);
63
        /* We have failed to restore original signal mask, all bets are off,
64
           so terminate the process */
65
        exit (EXIT_FAILURE);
66
    }
67

    
68
    if (err) {
69
        efunc = "pthread_create";
70
        goto err2;
71
    }
72

    
73
    return 0;
74

    
75
 err2:
76
    err2 = pthread_cond_destroy (&p->cond);
77
    if (err2) {
78
        logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
79
    }
80

    
81
 err1:
82
    err2 = pthread_mutex_destroy (&p->mutex);
83
    if (err2) {
84
        logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
85
    }
86

    
87
 err0:
88
    logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
89
    return -1;
90
}
91

    
92
int audio_pt_fini (struct audio_pt *p, const char *cap)
93
{
94
    int err, ret = 0;
95

    
96
    err = pthread_cond_destroy (&p->cond);
97
    if (err) {
98
        logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
99
        ret = -1;
100
    }
101

    
102
    err = pthread_mutex_destroy (&p->mutex);
103
    if (err) {
104
        logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
105
        ret = -1;
106
    }
107
    return ret;
108
}
109

    
110
int audio_pt_lock (struct audio_pt *p, const char *cap)
111
{
112
    int err;
113

    
114
    err = pthread_mutex_lock (&p->mutex);
115
    if (err) {
116
        logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
117
        return -1;
118
    }
119
    return 0;
120
}
121

    
122
int audio_pt_unlock (struct audio_pt *p, const char *cap)
123
{
124
    int err;
125

    
126
    err = pthread_mutex_unlock (&p->mutex);
127
    if (err) {
128
        logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
129
        return -1;
130
    }
131
    return 0;
132
}
133

    
134
int audio_pt_wait (struct audio_pt *p, const char *cap)
135
{
136
    int err;
137

    
138
    err = pthread_cond_wait (&p->cond, &p->mutex);
139
    if (err) {
140
        logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
141
        return -1;
142
    }
143
    return 0;
144
}
145

    
146
int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
147
{
148
    int err;
149

    
150
    err = pthread_mutex_unlock (&p->mutex);
151
    if (err) {
152
        logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
153
        return -1;
154
    }
155
    err = pthread_cond_signal (&p->cond);
156
    if (err) {
157
        logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
158
        return -1;
159
    }
160
    return 0;
161
}
162

    
163
int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
164
{
165
    int err;
166
    void *ret;
167

    
168
    err = pthread_join (p->thread, &ret);
169
    if (err) {
170
        logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
171
        return -1;
172
    }
173
    *arg = ret;
174
    return 0;
175
}