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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1933 - (hide annotations) (download) (as text)
Thu Jul 9 17:37:41 2009 UTC (14 years, 10 months ago) by persson
File MIME type: text/x-c++hdr
File size: 7312 byte(s)
* fixed low-level ConditionServer usage bug that caused lockups on
  Windows

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 persson 1764 * Copyright (C) 2005 - 2008 Christian Schoenebeck *
7 schoenebeck 53 * *
8     * This program is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this program; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #ifndef __CONDITIONSERVER_H__
25     #define __CONDITIONSERVER_H__
26    
27     #include "Mutex.h"
28 persson 1764 #include "SynchronizedConfig.h"
29 schoenebeck 53
30 schoenebeck 880 namespace LinuxSampler {
31    
32 schoenebeck 53 /**
33     * Thread safe condition for semi real time operation
34     *
35     * Sense behind the ConditionServer is to sync a boolean condition between
36     * one real time thread (RTT) and n non real time threads (NRTT).
37     *
38     * 1 Real Time Thread <--> Condition Object <--> n Non Real Time Threads
39     *
40     * The non real time threads set the condition by calling Push(), this
41     * method will immediately return if the current condition already equals
42     * the desired condition given with Push(), if it's not equal then Push()
43     * will cause a request to change the condition and will block until the
44 persson 1764 * condition actually changed, which happens when the RTT is outside its
45     * critical region, or has called the Pop() method, which will also return
46     * the new condition to the RTT.
47 schoenebeck 53 *
48     * Advantage of this technique is that the RTT doesn't has to execute system
49 persson 1764 * calls whenever it wants to check for a condition change. Disadvantage on
50     * the other hand is that the NRTTs might be blocked for some time, but this
51     * is usually unproblematic for NRTTs.
52 schoenebeck 53 */
53     class ConditionServer {
54     public:
55     ConditionServer();
56    
57    
58     // methods for non realtime threads (0..n NRTTs)
59    
60     /**
61     * Set condition to \a bCondition. If current condition already
62     * equals \a bCondition, then this method will immediately return,
63     * if not it will block the calling thread until the condition
64     * actually changed to the requested condition (which happens when
65 persson 1764 * Pop() has been called by the real time thread, or when the real
66     * time thread is outside its critical region). If there are multiple
67 schoenebeck 53 * non real time threads calling Push() only one by one will be
68     * served, all others blocked meanwhile. When the calling thread
69     * returns from Push() the Push() method will still be blocked
70     * against other NRTTs, so the thread can safely enter a critical
71     * section and has to Unlock() right after it left it's critical
72     * section, so other NRTTs can pass Push().
73     *
74     * @param bCondition - condition to set
75     * @param TimeoutSeconds - optional: max. wait time in seconds
76     * (default: 0s)
77     * @param TimeoutNanoSeconds - optional: max wait time in nano
78     * seconds (default: 0ns)
79     * @returns bool pointer with condition before Push() call, NULL if
80     * timeout exceeded
81     * @see Unlock()
82     */
83     bool* Push(bool bCondition, long TimeoutSeconds = 0L, long TimeoutNanoSeconds = 0L);
84    
85     /**
86     * Same as Push(), except that PushAndUnlock() will unlock the
87     * ConditionServer right after so that other NRTTs can follow to
88     * pass push. You should only call this method if you're sure that
89     * no other NRTT will change the condition, otherwise you should
90     * call Push() instead, execute the critical section and manually
91     * unlock at the end of the critical section.
92     *
93     * @param bCondition - condition to set
94     * @param TimeoutSeconds - optional: max. wait time in seconds
95     * (default: 0s)
96     * @param TimeoutNanoSeconds - optional: max wait time in nano
97     * seconds (default: 0ns)
98 persson 1933 * @param bAlreadyLocked - optional: you must set this to true if
99     * you have called Push() before and are
100     * using PushAndUnlock to end the
101     * critical region (default: false)
102 schoenebeck 53 * @returns bool pointer with condition before PushAndUnlock()
103     * call, NULL if timeout exceeded
104     */
105 persson 1933 bool* PushAndUnlock(bool bCondition, long TimeoutSeconds = 0L, long TimeoutNanoSeconds = 0L, bool bAlreadyLocked = false);
106 schoenebeck 53
107 persson 1933 void PushAndUnlock2(bool bCondition);
108    
109 schoenebeck 53 /**
110     * Should be called by the NRTT after it left it's critical section
111     * to unlock the ConditionServer and give other NRTTs the chance to
112     * pass Push().
113     */
114     void Unlock();
115    
116     /**
117     * Returns unsafely the current condition. This method will not
118     * block and should only be used in a not thread critical context.
119     *
120     * @returns current condition (unsafe)
121     */
122     bool GetUnsafe();
123    
124    
125    
126     // method for real time thread (1 RTT)
127    
128     /**
129 persson 1764 * Should be called by the real time thread (RTT) at the
130     * beginning of the critical region to check for a condition
131     * change. If an NRTT requested a condition change by calling
132     * Push() or PushAndUnlock() the NRTT will be blocked until
133     * it knows that the RTT will not go into its critical region
134     * without being notified about the condition change.
135 schoenebeck 53 *
136     * @returns current condition
137     */
138 persson 1764 bool Pop() {
139     return Reader.Lock();
140     }
141 schoenebeck 53
142 persson 1764 /**
143     * Should be called by the real time thread (RTT) at the end of
144     * the critical region.
145     */
146     void RttDone() {
147     Reader.Unlock();
148     }
149    
150 schoenebeck 53 protected:
151 persson 1764 SynchronizedConfig<bool> Condition;
152     SynchronizedConfig<bool>::Reader Reader;
153 schoenebeck 53 bool bOldCondition;
154     Mutex PushMutex;
155     };
156    
157 schoenebeck 880 } // namespace LinuxSampler
158    
159 schoenebeck 53 #endif // __CONDITIONSERVER_H__

  ViewVC Help
Powered by ViewVC