#ifndef foopulsecoreaupdatehfoo #define foopulsecoreaupdatehfoo /*** This file is part of PulseAudio. Copyright 2009 Lennart Poettering PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PulseAudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***/ typedef struct pa_aupdate pa_aupdate; pa_aupdate *pa_aupdate_new(void); void pa_aupdate_free(pa_aupdate *a); /* Will return 0, or 1, depending on which copy of the data the caller * should look at */ unsigned pa_aupdate_read_begin(pa_aupdate *a); void pa_aupdate_read_end(pa_aupdate *a); /* Will return 0, or 1, depending which copy of the data the caller * should modify */ unsigned pa_aupdate_write_begin(pa_aupdate *a); void pa_aupdate_write_end(pa_aupdate *a); /* Will return 0, or 1, depending which copy of the data the caller * should modify. Each time called this will return the opposite of * the previous pa_aupdate_write_begin()/pa_aupdate_write_swap() * call. Should only be called between pa_aupdate_write_begin() and * pa_aupdate_write_end() */ unsigned pa_aupdate_write_swap(pa_aupdate *a); /* * This infrastructure allows lock-free updates of arbitrary data * structures in an rcu'ish way: two copies of the data structure * should be exisiting. One side ('the reader') has read access to one * of the two data structure at a time. It does not have to lock it, * however it needs to signal that it is using it/stopped using * it. The other side ('the writer') modifes the second data structure, * and then atomically swaps the two data structures, followed by a * modification of the other one. * * This is intended to be used for cases where the reader side needs * to be fast while the writer side can be slow. * * The reader side is signal handler safe. * * The writer side lock is not recursive. The reader side is. * * There may be multiple readers and multiple writers at the same * time. * * Usage is like this: * * static struct foo bar[2]; * static pa_aupdate *a; * * reader() { * unsigned j; * * j = pa_update_read_begin(a); * * ... read the data structure bar[j] ... * * pa_update_read_end(a); * } * * writer() { * unsigned j; * * j = pa_update_write_begin(a); * * ... update the data structure bar[j] ... * * j = pa_update_write_swap(a); * * ... update the data structure bar[j], the same way as above ... * * pa_update_write_end(a) * } * * In some cases keeping both structures up-to-date might not be * necessary, since they are fully rebuilt on each iteration * anyway. In that case you may leave the _write_swap() call out, it * will then be done implicitly in the _write_end() invocation. */ #endif