Correct install target
[jack2.git] / windows / JackWinThread.cpp
blobfff76f658ccda079153b4400b7ef8f70a7e9af22
1 /*
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"
23 #include <assert.h>
25 namespace Jack
28 DWORD WINAPI JackWinThread::ThreadHandler(void* arg)
30 JackWinThread* obj = (JackWinThread*)arg;
31 JackRunnableInterface* runnable = obj->fRunnable;
33 // Call Init method
34 if (!runnable->Init()) {
35 jack_error("Thread init fails: thread quits");
36 return 0;
39 // Signal creation thread when started with StartSync
40 if (!obj->fRunning) {
41 obj->fRunning = true;
42 SetEvent(obj->fEvent);
45 JackLog("ThreadHandler: start\n");
47 // If Init succeed, start the thread loop
48 bool res = true;
49 while (obj->fRunning && res) {
50 res = runnable->Execute();
53 SetEvent(obj->fEvent);
54 JackLog("ThreadHandler: exit\n");
55 return 0;
58 JackWinThread::JackWinThread(JackRunnableInterface* runnable)
59 : JackThread(runnable, 0, false, 0)
61 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
62 fThread = NULL;
63 assert(fEvent);
66 JackWinThread::~JackWinThread()
68 CloseHandle(fEvent);
71 int JackWinThread::Start()
73 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
74 if (fEvent == NULL) {
75 jack_error("Cannot create event error = %d", GetLastError());
76 return -1;
79 fRunning = true;
81 // Check if the thread was correctly started
82 if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
83 fRunning = false;
84 return -1;
85 } else {
86 return 0;
90 int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg)
92 DWORD id;
94 if (realtime) {
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());
101 return -1;
104 if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) {
105 jack_error("Cannot set priority class = %d", GetLastError());
106 return -1;
109 return 0;
111 } else {
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());
118 return -1;
121 return 0;
125 int JackWinThread::StartSync()
127 DWORD id;
129 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
130 if (fEvent == NULL) {
131 jack_error("Cannot create event error = %d", GetLastError());
132 return -1;
135 if (fRealTime) {
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());
142 return -1;
145 if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
146 jack_error("Thread has not started");
147 return -1;
150 if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
151 jack_error("Cannot set priority class = %d", GetLastError());
152 return -1;
155 return 0;
157 } else {
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());
164 return -1;
167 if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
168 jack_error("Thread has not started");
169 return -1;
172 return 0;
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");
185 fThread = NULL;
186 fRunning = false;
187 return 0;
188 } else {
189 return -1;
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);
200 fThread = NULL;
201 return 0;
202 } else {
203 return -1;
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");
224 return 0;
225 } else {
226 jack_error("Cannot set thread priority = %d", GetLastError());
227 return -1;
230 int JackWinThread::DropRealTime()
232 return DropRealTimeImp(fThread);
235 int JackWinThread::DropRealTimeImp(pthread_t thread)
237 if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
238 return 0;
239 } else {
240 jack_error("Cannot set thread priority = %d", GetLastError());
241 return -1;
245 pthread_t JackWinThread::GetThreadID()
247 return fThread;
250 } // end of namespace