]> git.vomp.tv Git - vompclient.git/blob - threadwin.cc
OSDOpenVG: Render on demand: Fix backing out of a view render race
[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         pthread=threadCond=threadCondMutex=threadKillable=NULL;
26 }
27
28 ThreadWin::~ThreadWin()
29 {
30     if (pthread) CloseHandle(pthread);
31     if (threadCond) CloseHandle(threadCond);
32     if (threadCondMutex) CloseHandle(threadCondMutex);
33     if (threadKillable) CloseHandle(threadKillable);
34 }
35
36
37 // Undeclared functions, only for use in this file to start the thread
38 DWORD WINAPI threadInternalStart(void *arg)
39 {
40   Thread *t = (Thread *)arg;
41   t->threadInternalStart2();
42   return 0;
43 }
44
45 int ThreadWin::threadStart()
46 {
47   threadCond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
48   if (threadCond == NULL) return 0;
49   threadKillable = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
50   if (threadKillable == NULL) return 0;
51   threadCondMutex = CreateMutex(NULL,FALSE,NULL);
52   if (threadCondMutex == NULL)
53   {
54     CloseHandle(threadCond);
55     return 0;
56   }
57
58   threadActive = 1;
59   
60   pthread = CreateThread(NULL, 0, threadInternalStart, (void*)this,0, &threadId);
61   if (pthread == NULL)
62   {
63     CloseHandle(threadCond);
64     CloseHandle(threadCondMutex);
65     CloseHandle(threadKillable);
66     return 0;
67   }
68   return 1;
69 }
70
71 void ThreadWin::threadStop()
72 {
73   threadActive = 0;
74   // Signal thread here in case it's waiting
75   threadSignal();
76   WaitForSingleObject(pthread, INFINITE);
77   this->threadPostStopCleanup();
78 }
79
80 void ThreadWin::threadCancel()
81 {
82   threadActive = 0;
83   threadSignalNoLock();
84   HANDLE objs[]={threadKillable,pthread};
85   if (WaitForMultipleObjects(2,objs,FALSE,INFINITE)==WAIT_OBJECT_0) {
86     TerminateThread(pthread, 0);
87   }
88   this->threadPostStopCleanup();
89 }
90
91 void ThreadWin::threadCheckExit()
92 {
93   if (!threadActive) ExitThread(NULL);
94 }
95
96 void ThreadWin::threadLock()
97 {
98   WaitForSingleObject(threadCondMutex, INFINITE);
99 }
100
101 void ThreadWin::threadUnlock()
102 {
103   ReleaseMutex(threadCondMutex);
104 }
105
106 void ThreadWin::threadSignal()
107 {
108   WaitForSingleObject(threadCondMutex, INFINITE);
109  // PulseEvent(threadCond);
110   SetEvent(threadCond);
111   ReleaseMutex(threadCondMutex);
112 }
113
114 void ThreadWin::threadSignalNoLock()
115 {
116 //    PulseEvent(threadCond);
117         SetEvent(threadCond);
118 }
119
120 void ThreadWin::threadWaitForSignal()
121 {
122   threadUnlock();
123   WaitForSingleObject(threadCond,INFINITE);
124   ResetEvent(threadCond);
125   threadLock();
126 }
127
128 void ThreadWin::threadWaitForSignalTimed(struct timespec* ts)
129 {
130         threadUnlock();
131         HANDLE handles[2] ={threadCond, NULL};
132         LARGE_INTEGER duration;
133         duration.QuadPart=(((LONGLONG)ts->tv_sec)*1000LL*1000LL*10LL+((LONGLONG)ts->tv_nsec)/100LL)+WINDOWS_TIME_BASE_OFFSET;
134         SYSTEMTIME debug;
135         FILETIME debugfile;
136         GetSystemTime(&debug);
137         SystemTimeToFileTime(&debug,&debugfile);
138         
139         handles[1]=CreateWaitableTimer(NULL,TRUE,NULL);
140         SetWaitableTimer(handles[1], &duration, 0, NULL, NULL, 0);
141         WaitForMultipleObjects(2,handles,FALSE,INFINITE);
142         ResetEvent(threadCond);
143         CloseHandle(handles[1]);
144         threadLock();
145 }
146
147 void ThreadWin::threadSetKillable()
148 {
149   //WIN32:Ignore or use a separate Event Object to simulate this
150     SetEvent(threadKillable);
151 }
152
153 void ThreadWin::threadSuicide()
154 {
155 /*  if(!pthread_detach(pthread_self()))
156   {
157     MILLISLEEP(1000);
158     if(!pthread_detach(pthread_self()))
159     {
160       MILLISLEEP(1000);
161       pthread_detach(pthread_self());
162     }
163   }
164 */
165     
166     ExitThread(0);
167 }
168
169 unsigned int ThreadWin::getThreadID()
170 {
171     return threadId;
172 }
173
174 unsigned int ThreadWin::thisThreadID() // returns the ID of the calling thread
175 {
176   return GetCurrentThreadId();
177 }