~diwic/ubuntu/lucid/pulseaudio/bugfixes

« back to all changes in this revision

Viewing changes to src/pulsecore/fdsem.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2008-11-04 15:46:00 UTC
  • mfrom: (1.2.1 upstream) (1.1.6 lenny)
  • Revision ID: james.westby@ubuntu.com-20081104154600-hlzknpcazaam0nxm
Tags: 0.9.13-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Don't build against, and create jack package. Jack is not in main.
  - Remove --disable-per-user-esound-socket from configure flags, as we still
    want per user esound sockets.
  - Remove stop links from rc0 and rc6.
  - Change default resample algorithm and bubffer size.
  - Add alsa configuration files to route alsa applications via pulseaudio.
  - Move libasound2-plugins from Recommends to Depends.
* debian/pulseaudio.preinst: When upgrading from intrepid, remove
  /etc/X11/Xsession.d/70pulseaudio, as this was used to minimize a race
  condition when starting GNOME in intrepid. This race should not exist in
  jaunty once libcanberra is built to use pulseaudio as a backend.
* Do not spawn a pulseaudio server if clients fail to find a running server.
* Remove explicit version dependency for libspeex-dev to allow the package
  to be built for now.
* Regenerate autotools files to work with Ubuntu's newer libtool/libltdl.
* debian/control: libpulsecore5 -> libpulsecore8 to match the library
  soname.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id$ */
2
 
 
3
1
/***
4
2
  This file is part of PulseAudio.
5
3
 
43
41
#include <pulsecore/pipe.h>
44
42
#endif
45
43
 
46
 
#ifdef __linux__
47
 
 
48
 
#if !defined(__NR_eventfd) && defined(__i386__)
49
 
#define __NR_eventfd 323
50
 
#endif
51
 
 
52
 
#if !defined(__NR_eventfd) && defined(__x86_64__)
53
 
#define __NR_eventfd 284
54
 
#endif
55
 
 
56
 
#if !defined(__NR_eventfd) && defined(__arm__)
57
 
#define __NR_eventfd (__NR_SYSCALL_BASE+351)
58
 
#endif
59
 
 
60
 
#if !defined(SYS_eventfd) && defined(__NR_eventfd)
61
 
#define SYS_eventfd __NR_eventfd
62
 
#endif
63
 
 
64
 
#ifdef SYS_eventfd
65
 
#define HAVE_EVENTFD
66
 
 
67
 
static inline long eventfd(unsigned count) {
68
 
    return syscall(SYS_eventfd, count);
69
 
}
70
 
 
71
 
#endif
 
44
#ifdef HAVE_SYS_EVENTFD_H
 
45
#include <sys/eventfd.h>
72
46
#endif
73
47
 
74
48
#include "fdsem.h"
75
49
 
76
50
struct pa_fdsem {
77
51
    int fds[2];
78
 
#ifdef HAVE_EVENTFD
 
52
#ifdef HAVE_SYS_EVENTFD_H
79
53
    int efd;
80
54
#endif
81
 
    pa_atomic_t waiting;
82
 
    pa_atomic_t signalled;
83
 
    pa_atomic_t in_pipe;
 
55
 
 
56
    pa_fdsem_data *data;
84
57
};
85
58
 
86
59
pa_fdsem *pa_fdsem_new(void) {
87
60
    pa_fdsem *f;
88
61
 
89
 
    f = pa_xnew(pa_fdsem, 1);
 
62
    f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data)));
90
63
 
91
 
#ifdef HAVE_EVENTFD
92
 
    if ((f->efd = eventfd(0)) >= 0) {
 
64
#ifdef HAVE_SYS_EVENTFD_H
 
65
    if ((f->efd = eventfd(0, 0)) >= 0) {
93
66
        pa_make_fd_cloexec(f->efd);
94
67
        f->fds[0] = f->fds[1] = -1;
95
 
 
96
68
    } else
97
69
#endif
98
70
    {
105
77
        pa_make_fd_cloexec(f->fds[1]);
106
78
    }
107
79
 
108
 
    pa_atomic_store(&f->waiting, 0);
109
 
    pa_atomic_store(&f->signalled, 0);
110
 
    pa_atomic_store(&f->in_pipe, 0);
 
80
    f->data = (pa_fdsem_data*) ((uint8_t*) f + PA_ALIGN(sizeof(pa_fdsem)));
 
81
 
 
82
    pa_atomic_store(&f->data->waiting, 0);
 
83
    pa_atomic_store(&f->data->signalled, 0);
 
84
    pa_atomic_store(&f->data->in_pipe, 0);
 
85
 
 
86
    return f;
 
87
}
 
88
 
 
89
pa_fdsem *pa_fdsem_open_shm(pa_fdsem_data *data, int event_fd) {
 
90
    pa_fdsem *f = NULL;
 
91
 
 
92
    pa_assert(data);
 
93
    pa_assert(event_fd >= 0);
 
94
 
 
95
#ifdef HAVE_SYS_EVENTFD_H
 
96
    f = pa_xnew(pa_fdsem, 1);
 
97
 
 
98
    f->efd = event_fd;
 
99
    pa_make_fd_cloexec(f->efd);
 
100
    f->fds[0] = f->fds[1] = -1;
 
101
    f->data = data;
 
102
#endif
 
103
 
 
104
    return f;
 
105
}
 
106
 
 
107
pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {
 
108
    pa_fdsem *f = NULL;
 
109
 
 
110
    pa_assert(data);
 
111
    pa_assert(event_fd);
 
112
 
 
113
#ifdef HAVE_SYS_EVENTFD_H
 
114
 
 
115
    f = pa_xnew(pa_fdsem, 1);
 
116
 
 
117
    if ((f->efd = eventfd(0, 0)) < 0) {
 
118
        pa_xfree(f);
 
119
        return NULL;
 
120
    }
 
121
 
 
122
    pa_make_fd_cloexec(f->efd);
 
123
    f->fds[0] = f->fds[1] = -1;
 
124
    f->data = data;
 
125
 
 
126
    pa_atomic_store(&f->data->waiting, 0);
 
127
    pa_atomic_store(&f->data->signalled, 0);
 
128
    pa_atomic_store(&f->data->in_pipe, 0);
 
129
 
 
130
#endif
111
131
 
112
132
    return f;
113
133
}
115
135
void pa_fdsem_free(pa_fdsem *f) {
116
136
    pa_assert(f);
117
137
 
118
 
#ifdef HAVE_EVENTFD
 
138
#ifdef HAVE_SYS_EVENTFD_H
119
139
    if (f->efd >= 0)
120
140
        pa_close(f->efd);
121
141
#endif
128
148
    ssize_t r;
129
149
    pa_assert(f);
130
150
 
131
 
    if (pa_atomic_load(&f->in_pipe) <= 0)
 
151
    if (pa_atomic_load(&f->data->in_pipe) <= 0)
132
152
        return;
133
153
 
134
154
    do {
135
155
        char x[10];
136
156
 
137
 
#ifdef HAVE_EVENTFD
 
157
#ifdef HAVE_SYS_EVENTFD_H
138
158
        if (f->efd >= 0) {
139
159
            uint64_t u;
140
160
 
151
171
            continue;
152
172
        }
153
173
 
154
 
    } while (pa_atomic_sub(&f->in_pipe, r) > r);
 
174
    } while (pa_atomic_sub(&f->data->in_pipe, (int) r) > (int) r);
155
175
}
156
176
 
157
177
void pa_fdsem_post(pa_fdsem *f) {
158
178
    pa_assert(f);
159
179
 
160
 
    if (pa_atomic_cmpxchg(&f->signalled, 0, 1)) {
 
180
    if (pa_atomic_cmpxchg(&f->data->signalled, 0, 1)) {
161
181
 
162
 
        if (pa_atomic_load(&f->waiting)) {
 
182
        if (pa_atomic_load(&f->data->waiting)) {
163
183
            ssize_t r;
164
184
            char x = 'x';
165
185
 
166
 
            pa_atomic_inc(&f->in_pipe);
 
186
            pa_atomic_inc(&f->data->in_pipe);
167
187
 
168
188
            for (;;) {
169
189
 
170
 
#ifdef HAVE_EVENTFD
 
190
#ifdef HAVE_SYS_EVENTFD_H
171
191
                if (f->efd >= 0) {
172
192
                    uint64_t u = 1;
173
193
 
194
214
 
195
215
    flush(f);
196
216
 
197
 
    if (pa_atomic_cmpxchg(&f->signalled, 1, 0))
 
217
    if (pa_atomic_cmpxchg(&f->data->signalled, 1, 0))
198
218
        return;
199
219
 
200
 
    pa_atomic_inc(&f->waiting);
 
220
    pa_atomic_inc(&f->data->waiting);
201
221
 
202
 
    while (!pa_atomic_cmpxchg(&f->signalled, 1, 0)) {
 
222
    while (!pa_atomic_cmpxchg(&f->data->signalled, 1, 0)) {
203
223
        char x[10];
204
224
        ssize_t r;
205
225
 
206
 
#ifdef HAVE_EVENTFD
 
226
#ifdef HAVE_SYS_EVENTFD_H
207
227
        if (f->efd >= 0) {
208
228
            uint64_t u;
209
229
 
221
241
            continue;
222
242
        }
223
243
 
224
 
        pa_atomic_sub(&f->in_pipe, r);
 
244
        pa_atomic_sub(&f->data->in_pipe, (int) r);
225
245
    }
226
246
 
227
 
    pa_assert_se(pa_atomic_dec(&f->waiting) >= 1);
 
247
    pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1);
228
248
}
229
249
 
230
250
int pa_fdsem_try(pa_fdsem *f) {
232
252
 
233
253
    flush(f);
234
254
 
235
 
    if (pa_atomic_cmpxchg(&f->signalled, 1, 0))
 
255
    if (pa_atomic_cmpxchg(&f->data->signalled, 1, 0))
236
256
        return 1;
237
257
 
238
258
    return 0;
241
261
int pa_fdsem_get(pa_fdsem *f) {
242
262
    pa_assert(f);
243
263
 
244
 
#ifdef HAVE_EVENTFD
 
264
#ifdef HAVE_SYS_EVENTFD_H
245
265
    if (f->efd >= 0)
246
266
        return f->efd;
247
267
#endif
254
274
 
255
275
    flush(f);
256
276
 
257
 
    if (pa_atomic_cmpxchg(&f->signalled, 1, 0))
 
277
    if (pa_atomic_cmpxchg(&f->data->signalled, 1, 0))
258
278
        return -1;
259
279
 
260
 
    pa_atomic_inc(&f->waiting);
 
280
    pa_atomic_inc(&f->data->waiting);
261
281
 
262
 
    if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) {
263
 
        pa_assert_se(pa_atomic_dec(&f->waiting) >= 1);
 
282
    if (pa_atomic_cmpxchg(&f->data->signalled, 1, 0)) {
 
283
        pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1);
264
284
        return -1;
265
285
    }
266
286
    return 0;
269
289
int pa_fdsem_after_poll(pa_fdsem *f) {
270
290
    pa_assert(f);
271
291
 
272
 
    pa_assert_se(pa_atomic_dec(&f->waiting) >= 1);
 
292
    pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1);
273
293
 
274
294
    flush(f);
275
295
 
276
 
    if (pa_atomic_cmpxchg(&f->signalled, 1, 0))
 
296
    if (pa_atomic_cmpxchg(&f->data->signalled, 1, 0))
277
297
        return 1;
278
298
 
279
299
    return 0;