]> git.vomp.tv Git - vompclient.git/blob - threadwin.cc
Windows updates
[vompclient.git] / threadwin.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "threadwin.h"
22
23 ThreadWin::~ThreadWin()
24 {
25     CloseHandle(pthread);
26     CloseHandle(threadCond);
27     CloseHandle(threadCondMutex);
28     CloseHandle(threadKillable);
29 }
30
31
32 // Undeclared functions, only for use in this file to start the thread
33 DWORD WINAPI threadInternalStart(void *arg)
34 {
35   Thread *t = (Thread *)arg;
36   t->threadInternalStart2();
37   return 0;
38 }
39
40 int ThreadWin::threadStart()
41 {
42   threadCond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
43   if (threadCond == NULL) return 0;
44   threadKillable = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
45   if (threadKillable == NULL) return 0;
46   threadCondMutex = CreateMutex(NULL,FALSE,NULL);
47   if (threadCondMutex == NULL)
48   {
49     CloseHandle(threadCond);
50     return 0;
51   }
52
53   threadActive = 1;
54   
55   pthread = CreateThread(NULL, 0, threadInternalStart, (void*)this,0, &threadId);
56   if (pthread == NULL)
57   {
58     CloseHandle(threadCond);
59     CloseHandle(threadCondMutex);
60     CloseHandle(threadKillable);
61     return 0;
62   }
63   return 1;
64 }
65
66 void ThreadWin::threadStop()
67 {
68   threadActive = 0;
69   // Signal thread here in case it's waiting
70   threadSignal();
71   WaitForSingleObject(pthread, INFINITE);
72   this->threadPostStopCleanup();
73 }
74
75 void ThreadWin::threadCancel()
76 {
77   threadActive = 0;
78   threadSignalNoLock();
79   HANDLE objs[]={threadKillable,pthread};
80   if (WaitForMultipleObjects(2,objs,FALSE,INFINITE)==WAIT_OBJECT_0) {
81     TerminateThread(pthread, 0);
82   }
83   this->threadPostStopCleanup();
84 }
85
86 void ThreadWin::threadCheckExit()
87 {
88   if (!threadActive) ExitThread(NULL);
89 }
90
91 void ThreadWin::threadLock()
92 {
93   WaitForSingleObject(threadCondMutex, INFINITE);
94 }
95
96 void ThreadWin::threadUnlock()
97 {
98   ReleaseMutex(threadCondMutex);
99 }
100
101 void ThreadWin::threadSignal()
102 {
103   WaitForSingleObject(threadCondMutex, INFINITE);
104  // PulseEvent(threadCond);
105   SetEvent(threadCond);
106   ReleaseMutex(threadCondMutex);
107 }
108
109 void ThreadWin::threadSignalNoLock()
110 {
111 //    PulseEvent(threadCond);
112         SetEvent(threadCond);
113 }
114
115 void ThreadWin::threadWaitForSignal()
116 {
117   threadUnlock();
118   WaitForSingleObject(threadCond,INFINITE);
119   ResetEvent(threadCond);
120   threadLock();
121 }
122
123 void ThreadWin::threadWaitForSignalTimed(struct timespec* ts)
124 {
125         threadUnlock();
126         HANDLE handles[2] ={threadCond, NULL};
127         LARGE_INTEGER duration;
128         duration.QuadPart=(((LONGLONG)ts->tv_sec)*1000LL*1000LL*10LL+((LONGLONG)ts->tv_nsec)/100LL)+WINDOWS_TIME_BASE_OFFSET;
129         SYSTEMTIME debug;
130         FILETIME debugfile;
131         GetSystemTime(&debug);
132         SystemTimeToFileTime(&debug,&debugfile);
133         
134         handles[1]=CreateWaitableTimer(NULL,TRUE,NULL);
135         SetWaitableTimer(handles[1], &duration, 0, NULL, NULL, 0);
136         WaitForMultipleObjects(2,handles,FALSE,INFINITE);
137         ResetEvent(threadCond);
138         CloseHandle(handles[1]);
139         threadLock();
140 }
141
142 void ThreadWin::threadSetKillable()
143 {
144   //WIN32:Ignore or use a separate Event Object to simulate this
145     SetEvent(threadKillable);
146 }
147
148 void ThreadWin::threadSuicide()
149 {
150 /*  if(!pthread_detach(pthread_self()))
151   {
152     MILLISLEEP(1000);
153     if(!pthread_detach(pthread_self()))
154     {
155       MILLISLEEP(1000);
156       pthread_detach(pthread_self());
157     }
158   }
159 */
160     
161     ExitThread(0);
162 }
163
164 unsigned int ThreadWin::getThreadID()
165 {
166     return threadId;
167 }
168
169 unsigned int ThreadWin::thisThreadID() // returns the ID of the calling thread
170 {
171   return GetCurrentThreadId();
172 }