JackWinThread.cpp

00001 /*
00002 Copyright (C) 2001 Paul Davis 
00003 Copyright (C) 2004-2006 Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 
00019 */
00020 
00021 #include "JackWinThread.h"
00022 #include "JackError.h"
00023 #include <assert.h>
00024 
00025 namespace Jack
00026 {
00027 
00028 DWORD WINAPI JackWinThread::ThreadHandler(void* arg)
00029 {
00030     JackWinThread* obj = (JackWinThread*)arg;
00031     JackRunnableInterface* runnable = obj->fRunnable;
00032 
00033     // Call Init method
00034     if (!runnable->Init()) {
00035         jack_error("Thread init fails: thread quits");
00036         return 0;
00037     }
00038 
00039     // Signal creation thread when started with StartSync
00040     if (!obj->fRunning) {
00041         obj->fRunning = true;
00042         SetEvent(obj->fEvent);
00043     }
00044 
00045     JackLog("ThreadHandler: start\n");
00046 
00047     // If Init succeed, start the thread loop
00048     bool res = true;
00049     while (obj->fRunning && res) {
00050         res = runnable->Execute();
00051     }
00052   
00053     SetEvent(obj->fEvent);
00054     JackLog("ThreadHandler: exit\n");
00055     return 0;
00056 }
00057 
00058 JackWinThread::JackWinThread(JackRunnableInterface* runnable) 
00059         : JackThread(runnable, 0, false, 0)
00060 {
00061          fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00062          fThread = NULL;
00063          assert(fEvent);
00064 }
00065 
00066 JackWinThread::~JackWinThread()
00067 {
00068         CloseHandle(fEvent);
00069 }
00070 
00071 int JackWinThread::Start()
00072 {
00073     DWORD id;
00074 
00075     fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00076     if (fEvent == NULL) {
00077         jack_error("Cannot create event error = %d", GetLastError());
00078         return -1;
00079     }
00080 
00081     fRunning = true;
00082 
00083     if (fRealTime) {
00084 
00085         JackLog("Create RT thread\n");
00086         fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
00087 
00088         if (fThread == NULL) {
00089             jack_error("Cannot create thread error = %d", GetLastError());
00090             return -1;
00091         }
00092 
00093         if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
00094             jack_error("Cannot set priority class = %d", GetLastError());
00095             return -1;
00096         }
00097 
00098         return 0;
00099 
00100     } else {
00101 
00102         JackLog("Create non RT thread\n");
00103         fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
00104 
00105         if (fThread == NULL) {
00106             jack_error("Cannot create thread error = %d", GetLastError());
00107             return -1;
00108         }
00109 
00110         return 0;
00111     }
00112 }
00113 
00114 int JackWinThread::StartSync()
00115 {
00116     DWORD id;
00117 
00118     fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00119     if (fEvent == NULL) {
00120         jack_error("Cannot create event error = %d", GetLastError());
00121         return -1;
00122     }
00123 
00124     if (fRealTime) {
00125 
00126         JackLog("Create RT thread\n");
00127         fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
00128 
00129         if (fThread == NULL) {
00130             jack_error("Cannot create thread error = %d", GetLastError());
00131             return -1;
00132         }
00133 
00134         if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
00135             jack_error("Thread has not started");
00136             return -1;
00137         }
00138 
00139         if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
00140             jack_error("Cannot set priority class = %d", GetLastError());
00141             return -1;
00142         }
00143 
00144         return 0;
00145 
00146     } else {
00147 
00148         JackLog("Create non RT thread\n");
00149         fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
00150 
00151         if (fThread == NULL) {
00152             jack_error("Cannot create thread error = %d", GetLastError());
00153             return -1;
00154         }
00155 
00156         if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
00157             jack_error("Thread has not started");
00158             return -1;
00159         }
00160 
00161         return 0;
00162     }
00163 }
00164 
00165 // voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx
00166 
00167 int JackWinThread::Kill()
00168 {
00169     if (fThread) { // If thread has been started
00170         TerminateThread(fThread, 0);
00171                 WaitForSingleObject(fThread, INFINITE);
00172         CloseHandle(fThread);
00173                 JackLog("JackWinThread::Kill 2\n");
00174                 fThread = NULL;
00175                 fRunning = false; 
00176         return 0;
00177     } else {
00178         return -1;
00179     }
00180 }
00181 
00182 int JackWinThread::Stop()
00183 {
00184     if (fThread) { // If thread has been started
00185         JackLog("JackWinThread::Stop\n");
00186         fRunning = false; // Request for the thread to stop
00187         WaitForSingleObject(fEvent, INFINITE);
00188         CloseHandle(fThread);
00189                 fThread = NULL;
00190         return 0;
00191     } else {
00192         return -1;
00193     }
00194 }
00195 
00196 int JackWinThread::AcquireRealTime()
00197 {
00198     JackLog("JackWinThread::AcquireRealTime\n");
00199 
00200     if (fThread) {
00201         if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
00202             jack_error("Cannot set thread priority = %d", GetLastError());
00203             return -1;
00204         }
00205         JackLog("JackWinThread::AcquireRealTime OK\n");
00206         return 0;
00207     } else {
00208         return -1;
00209     }
00210 }
00211 
00212 int JackWinThread::AcquireRealTime(int priority)
00213 {
00214     JackLog("JackWinThread::AcquireRealTime priority = %ld\n", priority);
00215     return AcquireRealTime();
00216 }
00217 
00218 int JackWinThread::DropRealTime()
00219 {
00220     if (fThread) {
00221         if (!SetThreadPriority(fThread, THREAD_PRIORITY_NORMAL)) {
00222             jack_error("Cannot set thread priority = %d", GetLastError());
00223             return -1;
00224         }
00225         return 0;
00226     } else {
00227         return -1;
00228     }
00229 }
00230 
00231 pthread_t JackWinThread::GetThreadID()
00232 {
00233     return fThread;
00234 }
00235 
00236 } // end of namespace
00237 

Generated on Wed Jan 10 11:42:47 2007 for Jackdmp by  doxygen 1.4.5