Android release v6.7_preview1
[xcsoar.git] / src / Thread / SuspensibleThread.cpp
blobcf45eaa8e13b7b8675ffc8b91a0b884b6e6ada14
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
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.
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, MA 02111-1307, USA.
24 #include "Thread/SuspensibleThread.hpp"
26 #include <assert.h>
28 bool
29 SuspensibleThread::Start(bool _suspended)
31 #ifdef HAVE_POSIX
32 stop_received = false;
33 suspend_received = _suspended;
34 suspended = false;
35 #else
36 if (_suspended)
37 suspend_trigger.Signal();
38 else
39 suspend_trigger.Reset();
40 stop_trigger.Reset();
41 command_trigger.Reset();
42 suspended.Reset();
43 #endif
45 return Thread::Start();
48 void
49 SuspensibleThread::BeginStop()
51 #ifdef HAVE_POSIX
52 mutex.Lock();
53 stop_received = true;
54 command_trigger.Signal();
55 mutex.Unlock();
56 #else
57 stop_trigger.Signal();
58 command_trigger.Signal();
59 #endif
62 void
63 SuspensibleThread::BeginSuspend()
65 assert(!Thread::IsInside());
66 assert(Thread::IsDefined());
68 #ifdef HAVE_POSIX
69 mutex.Lock();
70 suspend_received = true;
71 command_trigger.Signal();
72 mutex.Unlock();
73 #else
74 suspend_trigger.Signal();
75 command_trigger.Signal();
76 #endif
79 void
80 SuspensibleThread::WaitUntilSuspended()
82 assert(!Thread::IsInside());
83 assert(Thread::IsDefined());
85 #ifdef HAVE_POSIX
86 mutex.Lock();
87 assert(suspend_received);
89 while (!suspended)
90 client_trigger.Wait(mutex);
91 mutex.Unlock();
92 #else
93 assert(suspend_trigger.Test());
95 suspended.Wait();
96 #endif
99 void
100 SuspensibleThread::Suspend()
102 BeginSuspend();
103 WaitUntilSuspended();
106 void
107 SuspensibleThread::Resume()
109 #ifdef HAVE_POSIX
110 mutex.Lock();
111 suspend_received = false;
112 command_trigger.Signal();
113 mutex.Unlock();
114 #else
115 suspend_trigger.Reset();
116 command_trigger.Signal();
117 #endif
120 bool
121 SuspensibleThread::IsCommandPending()
123 assert(Thread::IsInside());
125 #ifdef HAVE_POSIX
126 mutex.Lock();
127 bool result = stop_received || suspend_received;
128 mutex.Unlock();
129 return result;
130 #else
131 return stop_trigger.Test() || suspend_trigger.Test();
132 #endif
135 bool
136 SuspensibleThread::CheckStoppedOrSuspended()
138 assert(Thread::IsInside());
140 #ifdef HAVE_POSIX
141 mutex.Lock();
143 assert(!suspended);
145 if (!stop_received && suspend_received) {
146 suspended = true;
147 client_trigger.Signal();
148 while (!stop_received && suspend_received)
149 command_trigger.Wait(mutex);
150 suspended = false;
153 bool stop = stop_received;
154 mutex.Unlock();
155 return stop;
156 #else
157 if (stop_trigger.Test())
158 return true;
160 if (suspend_trigger.Test()) {
161 suspended.Signal();
162 while (suspend_trigger.Test() && !stop_trigger.Test())
163 command_trigger.WaitAndReset();
165 suspended.Reset();
168 return stop_trigger.Test();
169 #endif
172 bool
173 SuspensibleThread::WaitForStopped(unsigned timeout_ms)
175 assert(Thread::IsInside());
177 #ifdef HAVE_POSIX
178 mutex.Lock();
180 assert(!suspended);
181 suspended = true;
183 if (!stop_received)
184 command_trigger.Wait(mutex, timeout_ms);
186 if (!stop_received && suspend_received) {
187 client_trigger.Signal();
188 while (!stop_received && suspend_received)
189 command_trigger.Wait(mutex);
192 suspended = false;
193 bool stop = stop_received;
194 mutex.Unlock();
195 return stop;
196 #else
197 if (stop_trigger.Test())
198 return true;
200 suspended.Signal();
202 command_trigger.WaitAndReset(timeout_ms);
203 while (suspend_trigger.Test() && !stop_trigger.Test())
204 command_trigger.WaitAndReset();
206 suspended.Reset();
208 return stop_trigger.Test();
209 #endif