1 #ifndef foopulsecoreaupdatehfoo 2 #define foopulsecoreaupdatehfoo 3 4 /*** 5 This file is part of PulseAudio. 6 7 Copyright 2009 Lennart Poettering 8 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. 13 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. 18 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/>. 21 ***/ 22 23 typedef struct pa_aupdate pa_aupdate; 24 25 pa_aupdate *pa_aupdate_new(void); 26 void pa_aupdate_free(pa_aupdate *a); 27 28 /* Will return 0, or 1, depending on which copy of the data the caller 29 * should look at */ 30 unsigned pa_aupdate_read_begin(pa_aupdate *a); 31 void pa_aupdate_read_end(pa_aupdate *a); 32 33 /* Will return 0, or 1, depending which copy of the data the caller 34 * should modify */ 35 unsigned pa_aupdate_write_begin(pa_aupdate *a); 36 void pa_aupdate_write_end(pa_aupdate *a); 37 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); 44 45 /* 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. 54 * 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. 57 * 58 * The reader side is signal handler safe. 59 * 60 * The writer side lock is not recursive. The reader side is. 61 * 62 * There may be multiple readers and multiple writers at the same 63 * time. 64 * 65 * Usage is like this: 66 * 67 * static struct foo bar[2]; 68 * static pa_aupdate *a; 69 * 70 * reader() { 71 * unsigned j; 72 * 73 * j = pa_update_read_begin(a); 74 * 75 * ... read the data structure bar[j] ... 76 * 77 * pa_update_read_end(a); 78 * } 79 * 80 * writer() { 81 * unsigned j; 82 * 83 * j = pa_update_write_begin(a); 84 * 85 * ... update the data structure bar[j] ... 86 * 87 * j = pa_update_write_swap(a); 88 * 89 * ... update the data structure bar[j], the same way as above ... 90 * 91 * pa_update_write_end(a) 92 * } 93 * 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. 98 */ 99 100 #endif 101