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, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 typedef struct pa_aupdate pa_aupdate
;
27 pa_aupdate
*pa_aupdate_new(void);
28 void pa_aupdate_free(pa_aupdate
*a
);
30 /* Will return 0, or 1, depending on which copy of the data the caller
32 unsigned pa_aupdate_read_begin(pa_aupdate
*a
);
33 void pa_aupdate_read_end(pa_aupdate
*a
);
35 /* Will return 0, or 1, depending which copy of the data the caller
37 unsigned pa_aupdate_write_begin(pa_aupdate
*a
);
38 void pa_aupdate_write_end(pa_aupdate
*a
);
40 /* Will return 0, or 1, depending which copy of the data the caller
41 * should modify. Each time called this will return the opposite of
42 * the previous pa_aupdate_write_begin() / pa_aupdate_write_swap()
43 * call. Should only be called between pa_aupdate_write_begin() and
44 * pa_aupdate_write_end() */
45 unsigned pa_aupdate_write_swap(pa_aupdate
*a
);
48 * This infrastructure allows lock-free updates of arbitrary data
49 * structures in an rcu'ish way: two copies of the data structure
50 * should be exisiting. One side ('the reader') has read access to one
51 * of the two data structure at a time. It does not have to lock it,
52 * however it needs to signal that it is using it/stopped using
53 * it. The other side ('the writer') modifes the second data structure,
54 * and then atomically swaps the two data structures, followed by a
55 * modification of the other one.
57 * This is intended to be used for cases where the reader side needs
58 * to be fast while the writer side can be slow.
60 * The reader side is signal handler safe.
62 * The writer side lock is not recursive. The reader side is.
64 * There may be multiple readers and multiple writers at the same
69 * static struct foo bar[2];
70 * static pa_aupdate *a;
75 * j = pa_update_read_begin(a);
77 * ... read the data structure bar[j] ...
79 * pa_update_read_end(a);
85 * j = pa_update_write_begin(a);
87 * ... update the data structure bar[j] ...
89 * j = pa_update_write_swap(a);
91 * ... update the data structure bar[j], the same way as above ...
93 * pa_update_write_end(a)
96 * In some cases keeping both structures up-to-date might not be
97 * necessary, since they are fully rebuilt on each iteration
98 * anyway. In that case you may leave the _write_swap() call out, it
99 * will then be done implicitly in the _write_end() invocation.