OpenTTD
thread_os2.cpp
Go to the documentation of this file.
1 /* $Id: thread_os2.cpp 27670 2016-10-30 17:29:33Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "../stdafx.h"
13 #include "thread.h"
14 
15 #define INCL_DOS
16 #include <os2.h>
17 #include <process.h>
18 
19 #include "../safeguards.h"
20 
25 private:
26  TID thread;
28  void *param;
30 
31 public:
35  ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) :
36  thread(0),
37  proc(proc),
38  param(param),
39  self_destruct(self_destruct)
40  {
41  thread = _beginthread(stThreadProc, NULL, 1048576, this);
42  }
43 
44  /* virtual */ bool Exit()
45  {
46  _endthread();
47  return true;
48  }
49 
50  /* virtual */ void Join()
51  {
52  DosWaitThread(&this->thread, DCWW_WAIT);
53  this->thread = 0;
54  }
55 private:
60  static void stThreadProc(void *thr)
61  {
62  ((ThreadObject_OS2 *)thr)->ThreadProc();
63  }
64 
69  void ThreadProc()
70  {
71  /* Call the proc of the creator to continue this thread */
72  try {
73  this->proc(this->param);
74  } catch (OTTDThreadExitSignal e) {
75  } catch (...) {
76  NOT_REACHED();
77  }
78 
79  if (self_destruct) {
80  this->Exit();
81  delete this;
82  }
83  }
84 };
85 
86 /* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name)
87 {
88  ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL);
89  if (thread != NULL) *thread = to;
90  return true;
91 }
92 
96 class ThreadMutex_OS2 : public ThreadMutex {
97 private:
98  HMTX mutex;
99  HEV event;
101 
102 public:
103  ThreadMutex_OS2() : recursive_count(0)
104  {
105  DosCreateMutexSem(NULL, &mutex, 0, FALSE);
106  DosCreateEventSem(NULL, &event, 0, FALSE);
107  }
108 
109  /* virtual */ ~ThreadMutex_OS2()
110  {
111  DosCloseMutexSem(mutex);
112  DosCloseEventSem(event);
113  }
114 
115  /* virtual */ void BeginCritical(bool allow_recursive = false)
116  {
117  /* os2 mutex is recursive by itself */
118  DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT);
119  this->recursive_count++;
120  if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
121  }
122 
123  /* virtual */ void EndCritical(bool allow_recursive = false)
124  {
125  if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
126  this->recursive_count--;
127  DosReleaseMutexSem(mutex);
128  }
129 
130  /* virtual */ void WaitForSignal()
131  {
132  assert(this->recursive_count == 1); // Do we need to call Begin/EndCritical multiple times otherwise?
133  this->EndCritical();
134  DosWaitEventSem(event, SEM_INDEFINITE_WAIT);
135  this->BeginCritical();
136  }
137 
138  /* virtual */ void SendSignal()
139  {
140  DosPostEventSem(event);
141  }
142 };
143 
144 /* static */ ThreadMutex *ThreadMutex::New()
145 {
146  return new ThreadMutex_OS2();
147 }
void BeginCritical(bool allow_recursive=false)
Begin the critical section.
Definition: thread_os2.cpp:115
void EndCritical(bool allow_recursive=false)
End of the critical section.
Definition: thread_os2.cpp:123
static void stThreadProc(void *thr)
On thread creation, this function is called, which calls the real startup function.
Definition: thread_os2.cpp:60
void(* OTTDThreadFunc)(void *)
Definition of all thread entry functions.
Definition: thread.h:16
void * param
Parameter for the external thread procedure.
Definition: thread_os2.cpp:28
bool Exit()
Exit this thread.
Definition: thread_os2.cpp:44
Cross-platform Mutex.
Definition: thread.h:56
bool self_destruct
Free ourselves when done?
Definition: thread_os2.cpp:29
TID thread
System thread identifier.
Definition: thread_os2.cpp:26
Base of all threads.
void ThreadProc()
A new thread is created, and this function is called.
Definition: thread_os2.cpp:69
OTTDThreadFunc proc
External thread procedure.
Definition: thread_os2.cpp:27
OS/2 version of ThreadMutex.
Definition: thread_os2.cpp:96
static ThreadMutex * New()
Create a new mutex.
Definition: thread_none.cpp:32
HMTX mutex
The mutex.
Definition: thread_os2.cpp:98
HEV event
Event for waiting.
Definition: thread_os2.cpp:99
ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct)
Create a thread and start it, calling proc(param).
Definition: thread_os2.cpp:35
OS/2 version for ThreadObject.
Definition: thread_os2.cpp:24
void Join()
Join this thread.
Definition: thread_os2.cpp:50
void WaitForSignal()
Wait for a signal to be send.
Definition: thread_os2.cpp:130
uint recursive_count
Recursive lock count.
Definition: thread_os2.cpp:100
void SendSignal()
Send a signal and wake the &#39;thread&#39; that was waiting for it.
Definition: thread_os2.cpp:138
A Thread Object which works on all our supported OSes.
Definition: thread.h:24
Signal used for signalling we knowingly want to end the thread.
Definition: thread.h:19
static bool New(OTTDThreadFunc proc, void *param, ThreadObject **thread=NULL, const char *name=NULL)
Create a thread; proc will be called as first function inside the thread, with optional params...