Fix warnings reported by clang
[oweals/minetest.git] / src / jthread / pthread / jthread.cpp
1 /*
2
3     This file is a part of the JThread package, which contains some object-
4     oriented thread wrappers for different thread implementations.
5
6     Copyright (c) 2000-2006  Jori Liesenborgs (jori.liesenborgs@gmail.com)
7
8     Permission is hereby granted, free of charge, to any person obtaining a
9     copy of this software and associated documentation files (the "Software"),
10     to deal in the Software without restriction, including without limitation
11     the rights to use, copy, modify, merge, publish, distribute, sublicense,
12     and/or sell copies of the Software, and to permit persons to whom the
13     Software is furnished to do so, subject to the following conditions:
14
15     The above copyright notice and this permission notice shall be included in
16     all copies or substantial portions of the Software.
17
18     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24     DEALINGS IN THE SOFTWARE.
25
26 */
27
28 #include "jthread/jthread.h"
29 #include <assert.h>
30 #include <sys/time.h>
31 #include <time.h>
32 #include <stdlib.h>
33
34 #define UNUSED(expr) do { (void)(expr); } while (0)
35
36 JThread::JThread()
37 {
38         retval = NULL;
39         requeststop = false;
40         running = false;
41         started = false;
42 }
43
44 JThread::~JThread()
45 {
46         Kill();
47 }
48
49 void JThread::Wait() {
50         void* status;
51         if (started) {
52                 int pthread_join_retval = pthread_join(threadid,&status);
53                 assert(pthread_join_retval == 0);
54                 UNUSED(pthread_join_retval);
55                 started = false;
56         }
57 }
58
59 int JThread::Start()
60 {
61         int status;
62
63         if (running)
64         {
65                 return ERR_JTHREAD_ALREADYRUNNING;
66         }
67         requeststop = false;
68
69         pthread_attr_t attr;
70         pthread_attr_init(&attr);
71         //pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
72
73         continuemutex.Lock();
74         status = pthread_create(&threadid,&attr,TheThread,this);
75         pthread_attr_destroy(&attr);
76         if (status != 0)
77         {
78                 continuemutex.Unlock();
79                 return ERR_JTHREAD_CANTSTARTTHREAD;
80         }
81
82         /* Wait until 'running' is set */
83
84         while (!running)
85         {
86                 struct timespec req,rem;
87
88                 req.tv_sec = 0;
89                 req.tv_nsec = 1000000;
90                 nanosleep(&req,&rem);
91         }
92         started = true;
93
94         continuemutex.Unlock();
95
96         continuemutex2.Lock();
97         continuemutex2.Unlock();
98         return 0;
99 }
100
101 int JThread::Kill()
102 {
103         void* status;
104         if (!running)
105         {
106                 if (started) {
107                         int pthread_join_retval = pthread_join(threadid,&status);
108                         assert(pthread_join_retval == 0);
109                         UNUSED(pthread_join_retval);
110                         started = false;
111                 }
112                 return ERR_JTHREAD_NOTRUNNING;
113         }
114 #ifdef __ANDROID__
115         pthread_kill(threadid, SIGKILL);
116 #else
117         pthread_cancel(threadid);
118 #endif
119         if (started) {
120                 int pthread_join_retval = pthread_join(threadid,&status);
121                 assert(pthread_join_retval == 0);
122                 UNUSED(pthread_join_retval);
123                 started = false;
124         }
125         running = false;
126         return 0;
127 }
128
129 void *JThread::GetReturnValue()
130 {
131         void *val;
132
133         if (running) {
134                 val = NULL;
135         } else {
136                 val = retval;
137         }
138
139         return val;
140 }
141
142 bool JThread::IsSameThread()
143 {
144         return pthread_equal(pthread_self(), threadid);
145 }
146
147 void *JThread::TheThread(void *param)
148 {
149         JThread *jthread;
150         void *ret;
151
152         jthread = (JThread *)param;
153
154         jthread->continuemutex2.Lock();
155         jthread->running = true;
156
157         jthread->continuemutex.Lock();
158         jthread->continuemutex.Unlock();
159
160         ret = jthread->Thread();
161
162         jthread->running = false;
163
164         return NULL;
165 }
166
167 void JThread::ThreadStarted()
168 {
169         continuemutex2.Unlock();
170 }
171