Statistics
| Branch: | Revision:

root / audio / audio_pt_int.c @ 4b7c0418

History | View | Annotate | Download (3.8 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 logerr (struct audio_pt *pt, int err, 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
}