/[svn]/linuxsampler/trunk/src/common/SynchronizedConfig.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/common/SynchronizedConfig.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 840 - (show annotations) (download) (as text)
Sun Feb 26 13:00:08 2006 UTC (12 years, 7 months ago) by persson
File MIME type: text/x-c++hdr
File size: 5471 byte(s)
* fixed some concurrency problems between the lscp thread and the
  audio/midi threads for these commands: load engine, set channel
  audio output device, set channel midi input device/port/channel and
  remove channel. Thanks to Vincent Bongiorno for bug reports and
  testing.
* removed an autotools warning
* fixed an iterator bug
* minor code clean-ups

1 /***************************************************************************
2 * *
3 * Copyright (C) 2006 Andreas Persson *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
18 * MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #ifndef __SYNCHRONIZEDCONFIG_H__
22 #define __SYNCHRONIZEDCONFIG_H__
23
24 #include "atomic.h"
25
26 namespace LinuxSampler {
27
28 /**
29 * Thread safe management of configuration data, where the data is
30 * updated by a single non real time thread and read by a single
31 * real time thread.
32 *
33 * The synchronization is achieved by using two instances of the
34 * configuration data. The non real time thread gets access to the
35 * instance not currently in use by the real time thread by
36 * calling GetConfigForUpdate(). After the data is updated, the
37 * non real time thread must call SwitchConfig() and redo the
38 * update on the other instance. SwitchConfig() blocks until it is
39 * safe to modify the other instance.
40 *
41 * The real time thread calls Lock() to get access to the data,
42 * and Unlock() when it is finished reading the data. (Neither
43 * Lock nor Unlock will block the real time thread, or use any
44 * system calls.)
45 */
46 template<class T>
47 class SynchronizedConfig {
48 public:
49 SynchronizedConfig();
50
51 // methods for the real time thread
52
53 /**
54 * Gets the configuration object for use by the real time
55 * thread. The object is safe to use (read only) until
56 * Unlock() is called.
57 *
58 * @returns a reference to the configuration object to be
59 * read by the real time thread
60 */
61 const T& Lock() {
62 atomic_set(&lock, 1);
63 return config[atomic_read(&indexAtomic)];
64 }
65
66 /**
67 * Unlock the configuration object. Unlock() must be
68 * called by the real time thread after it has finished
69 * reading the configuration object. If the non real time
70 * thread is waiting in SwitchConfig() it will be awaken.
71 */
72 void Unlock() {
73 atomic_set(&lock, 0);
74 }
75
76
77 // methods for the non real time thread
78
79 /**
80 * Gets the configuration object for use by the non real
81 * time thread. The object returned is not in use by the
82 * real time thread, so it can safely be updated. After
83 * the update is done, the non real time thread must call
84 * SwitchConfig() and the same update must be done again.
85 *
86 * @returns a reference to the configuration object to be
87 * updated by the non real time thread
88 */
89 T& GetConfigForUpdate();
90
91 /**
92 * Atomically switch the newly updated configuration
93 * object with the one used by the real time thread, then
94 * wait for the real time thread to finish working with
95 * the old object before returning the old object.
96 * SwitchConfig() must be called by the non real time
97 * thread after an update has been done, and the object
98 * returned must be updated in the same way as the first.
99 *
100 * @returns a reference to the configuration object to be
101 * updated by the non real time thread
102 */
103 T& SwitchConfig();
104
105 private:
106 atomic_t lock;
107 atomic_t indexAtomic;
108 int updateIndex;
109 T config[2];
110 };
111
112 template<class T> SynchronizedConfig<T>::SynchronizedConfig() {
113 atomic_set(&lock, 0);
114 atomic_set(&indexAtomic, 0);
115 }
116
117 template<class T> T& SynchronizedConfig<T>::GetConfigForUpdate() {
118 updateIndex = atomic_read(&indexAtomic) ^ 1;
119 return config[updateIndex];
120 }
121
122 template<class T> T& SynchronizedConfig<T>::SwitchConfig() {
123 atomic_set(&indexAtomic, updateIndex);
124 while (atomic_read(&lock))
125 usleep(50000);
126 return config[updateIndex ^ 1];
127 }
128
129 } // namespace LinuxSampler
130
131 #endif

  ViewVC Help
Powered by ViewVC