1 #ifndef foopulsecoreaupdatehfoo
2 #define foopulsecoreaupdatehfoo
5 This file is part of PulseAudio.
7 Copyright 2009 Lennart Poettering
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as
11 published by the Free Software Foundation; either version 2.1 of the
12 License, or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
23 typedef struct pa_aupdate pa_aupdate;
25 pa_aupdate *pa_aupdate_new(void);
26 void pa_aupdate_free(pa_aupdate *a);
28 /* Will return 0, or 1, depending on which copy of the data the caller
30 unsigned pa_aupdate_read_begin(pa_aupdate *a);
31 void pa_aupdate_read_end(pa_aupdate *a);
33 /* Will return 0, or 1, depending which copy of the data the caller
35 unsigned pa_aupdate_write_begin(pa_aupdate *a);
36 void pa_aupdate_write_end(pa_aupdate *a);
38 /* Will return 0, or 1, depending which copy of the data the caller
39 * should modify. Each time called this will return the opposite of
40 * the previous pa_aupdate_write_begin() / pa_aupdate_write_swap()
41 * call. Should only be called between pa_aupdate_write_begin() and
42 * pa_aupdate_write_end() */
43 unsigned pa_aupdate_write_swap(pa_aupdate *a);
46 * This infrastructure allows lock-free updates of arbitrary data
47 * structures in an rcu'ish way: two copies of the data structure
48 * should be existing. One side ('the reader') has read access to one
49 * of the two data structure at a time. It does not have to lock it,
50 * however it needs to signal that it is using it/stopped using
51 * it. The other side ('the writer') modifies the second data structure,
52 * and then atomically swaps the two data structures, followed by a
53 * modification of the other one.
55 * This is intended to be used for cases where the reader side needs
56 * to be fast while the writer side can be slow.
58 * The reader side is signal handler safe.
60 * The writer side lock is not recursive. The reader side is.
62 * There may be multiple readers and multiple writers at the same
67 * static struct foo bar[2];
68 * static pa_aupdate *a;
73 * j = pa_update_read_begin(a);
75 * ... read the data structure bar[j] ...
77 * pa_update_read_end(a);
83 * j = pa_update_write_begin(a);
85 * ... update the data structure bar[j] ...
87 * j = pa_update_write_swap(a);
89 * ... update the data structure bar[j], the same way as above ...
91 * pa_update_write_end(a)
94 * In some cases keeping both structures up-to-date might not be
95 * necessary, since they are fully rebuilt on each iteration
96 * anyway. In that case you may leave the _write_swap() call out, it
97 * will then be done implicitly in the _write_end() invocation.