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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 840 - (hide annotations) (download) (as text)
Sun Feb 26 13:00:08 2006 UTC (18 years, 2 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 persson 840 /***************************************************************************
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