2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2006 Grame
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "JackWinThread.h"
22 #include "JackError.h"
28 DWORD WINAPI
JackWinThread::ThreadHandler(void* arg
)
30 JackWinThread
* obj
= (JackWinThread
*)arg
;
31 JackRunnableInterface
* runnable
= obj
->fRunnable
;
34 if (!runnable
->Init()) {
35 jack_error("Thread init fails: thread quits");
39 // Signal creation thread when started with StartSync
42 SetEvent(obj
->fEvent
);
45 JackLog("ThreadHandler: start\n");
47 // If Init succeed, start the thread loop
49 while (obj
->fRunning
&& res
) {
50 res
= runnable
->Execute();
53 SetEvent(obj
->fEvent
);
54 JackLog("ThreadHandler: exit\n");
58 JackWinThread::JackWinThread(JackRunnableInterface
* runnable
)
59 : JackThread(runnable
, 0, false, 0)
61 fEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
66 JackWinThread::~JackWinThread()
71 int JackWinThread::Start()
73 fEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
75 jack_error("Cannot create event error = %d", GetLastError());
81 // Check if the thread was correctly started
82 if (StartImp(&fThread
, fPriority
, fRealTime
, ThreadHandler
, this) < 0) {
90 int JackWinThread::StartImp(pthread_t
* thread
, int priority
, int realtime
, ThreadCallback start_routine
, void* arg
)
96 JackLog("Create RT thread\n");
97 *thread
= CreateThread(NULL
, 0, start_routine
, arg
, 0, &id
);
99 if (*thread
== NULL
) {
100 jack_error("Cannot create thread error = %d", GetLastError());
104 if (!SetThreadPriority(*thread
, THREAD_PRIORITY_TIME_CRITICAL
)) {
105 jack_error("Cannot set priority class = %d", GetLastError());
113 JackLog("Create non RT thread\n");
114 *thread
= CreateThread(NULL
, 0, start_routine
, arg
, 0, &id
);
116 if (thread
== NULL
) {
117 jack_error("Cannot create thread error = %d", GetLastError());
125 int JackWinThread::StartSync()
129 fEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
130 if (fEvent
== NULL
) {
131 jack_error("Cannot create event error = %d", GetLastError());
137 JackLog("Create RT thread\n");
138 fThread
= CreateThread(NULL
, 0, ThreadHandler
, (void*)this, 0, &id
);
140 if (fThread
== NULL
) {
141 jack_error("Cannot create thread error = %d", GetLastError());
145 if (WaitForSingleObject(fEvent
, 3000) != WAIT_OBJECT_0
) { // wait 3 sec
146 jack_error("Thread has not started");
150 if (!SetThreadPriority(fThread
, THREAD_PRIORITY_TIME_CRITICAL
)) {
151 jack_error("Cannot set priority class = %d", GetLastError());
159 JackLog("Create non RT thread\n");
160 fThread
= CreateThread(NULL
, 0, ThreadHandler
, (void*)this, 0, &id
);
162 if (fThread
== NULL
) {
163 jack_error("Cannot create thread error = %d", GetLastError());
167 if (WaitForSingleObject(fEvent
, 3000) != WAIT_OBJECT_0
) { // wait 3 sec
168 jack_error("Thread has not started");
176 // voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx
178 int JackWinThread::Kill()
180 if (fThread
) { // If thread has been started
181 TerminateThread(fThread
, 0);
182 WaitForSingleObject(fThread
, INFINITE
);
183 CloseHandle(fThread
);
184 JackLog("JackWinThread::Kill 2\n");
193 int JackWinThread::Stop()
195 if (fThread
) { // If thread has been started
196 JackLog("JackWinThread::Stop\n");
197 fRunning
= false; // Request for the thread to stop
198 WaitForSingleObject(fEvent
, INFINITE
);
199 CloseHandle(fThread
);
207 int JackWinThread::AcquireRealTime()
209 return (fThread
) ? AcquireRealTimeImp(fThread
, fPriority
) : -1;
212 int JackWinThread::AcquireRealTime(int priority
)
214 fPriority
= priority
;
215 return AcquireRealTime();
218 int JackWinThread::AcquireRealTimeImp(pthread_t thread
, int priority
)
220 JackLog("JackWinThread::AcquireRealTime\n");
222 if (SetThreadPriority(thread
, THREAD_PRIORITY_TIME_CRITICAL
)) {
223 JackLog("JackWinThread::AcquireRealTime OK\n");
226 jack_error("Cannot set thread priority = %d", GetLastError());
230 int JackWinThread::DropRealTime()
232 return DropRealTimeImp(fThread
);
235 int JackWinThread::DropRealTimeImp(pthread_t thread
)
237 if (SetThreadPriority(thread
, THREAD_PRIORITY_NORMAL
)) {
240 jack_error("Cannot set thread priority = %d", GetLastError());
245 pthread_t
JackWinThread::GetThreadID()
250 } // end of namespace