Branch data Line data Source code
1 : : /***
2 : : This file is part of PulseAudio.
3 : :
4 : : Copyright 2009 Lennart Poettering
5 : :
6 : : PulseAudio is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU Lesser General Public License as published
8 : : by the Free Software Foundation; either version 2.1 of the License,
9 : : or (at your option) any later version.
10 : :
11 : : PulseAudio is distributed in the hope that it will be useful, but
12 : : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU Lesser General Public License
17 : : along with PulseAudio; if not, write to the Free Software
18 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 : : USA.
20 : : ***/
21 : :
22 : : #ifdef HAVE_CONFIG_H
23 : : #include <config.h>
24 : : #endif
25 : :
26 : : #include <unistd.h>
27 : :
28 : : #include <pulsecore/atomic.h>
29 : : #include <pulsecore/macro.h>
30 : :
31 : : #include "fork-detect.h"
32 : :
33 : 0 : int pa_detect_fork(void) {
34 : : static pa_atomic_t pid = PA_ATOMIC_INIT((int) -1);
35 : :
36 : : /* Some really stupid applications (Hey, vim, that means you!)
37 : : * love to fork after initializing
38 : : * gtk/libcanberra/pulseaudio. This is really bad style. We
39 : : * however have to deal with this cleanly, so we try to detect the
40 : : * forks making sure all our calls fail cleanly after the fork. */
41 : :
42 : : pa_assert_cc(sizeof(pa_atomic_t) >= sizeof(pid_t));
43 : :
44 : : for (;;) {
45 : 0 : pid_t stored_pid = (pid_t) pa_atomic_load(&pid);
46 : :
47 : : /* First let's check whether the current pid matches the stored one */
48 [ # # ]: 0 : if (stored_pid == getpid())
49 : : return FALSE;
50 : :
51 : : /* Does it contain a different PID than ours? Then the process got forked. */
52 [ # # ]: 0 : if ((int) stored_pid != (int) -1)
53 : : return TRUE;
54 : :
55 : : /* Ok, it still contains no PID, then store it */
56 [ # # ]: 0 : if (pa_atomic_cmpxchg(&pid, (int) -1, (int) getpid()))
57 : : return FALSE;
58 : : }
59 : : }
|