]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/threadsgi.cpp
Possible crash fix from Ryan (patch #1194315).
[wxWidgets.git] / src / gtk / threadsgi.cpp
CommitLineData
7c351dad
GL
1/////////////////////////////////////////////////////////////////////////////
2// Name: threadsgi.cpp
3// Purpose: wxThread (SGI) Implementation
4// Author: Original from Wolfram Gloger/Guilhem Lavaux
5// Modified by:
6// Created: 04/22/98
7// RCS-ID: $Id$
8// Copyright: (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998)
65571936 9// Licence: wxWindows licence
7c351dad 10/////////////////////////////////////////////////////////////////////////////
14f355c2 11#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
7c351dad
GL
12#pragma implementation "thread.h"
13#endif
14
14f355c2
VS
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
e1bf3ad3 18#include "wx/thread.h"
7c351dad
GL
19#include <stdio.h>
20#include <unistd.h>
21
22#include <signal.h>
23#include <sys/wait.h>
24#include <sys/prctl.h>
82052aff
GL
25#include "wx/module.h"
26#include "wx/utils.h"
3069ac4e 27#include "wx/log.h"
7c351dad 28
83624f79
RR
29#include "gdk/gdk.h"
30#include "gtk/gtk.h"
31
32enum thread_state
33{
7c351dad
GL
34 STATE_IDLE = 0,
35 STATE_RUNNING,
36 STATE_CANCELED,
37 STATE_EXITED
38};
39
40/////////////////////////////////////////////////////////////////////////////
41// Static variables
42/////////////////////////////////////////////////////////////////////////////
43
44static int p_mainid;
6773ae19 45wxMutex *wxMainMutex;
7c351dad
GL
46
47#include "threadgui.inc"
48
49/////////////////////////////////////////////////////////////////////////////
50// Unix implementations (SGI threads)
51/////////////////////////////////////////////////////////////////////////////
52
53class wxMutexInternal {
54public:
55 abilock_t p_mutex;
56};
57
58wxMutex::wxMutex()
59{
b89156b5 60 m_locked = 0;
7c351dad
GL
61 p_internal = new wxMutexInternal;
62 init_lock(&(p_internal->p_mutex));
63}
64
65wxMutex::~wxMutex()
66{
b89156b5 67 if (m_locked > 0)
3069ac4e 68 wxLogDebug( "wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked );
b89156b5 69 delete p_internal;
7c351dad
GL
70}
71
b89156b5 72wxMutexError wxMutex::Lock()
7c351dad
GL
73{
74 spin_lock(&(p_internal->p_mutex));
b89156b5 75 m_locked++;
cffee23b 76 return wxMUTEX_NO_ERROR;
7c351dad
GL
77}
78
b89156b5 79wxMutexError wxMutex::TryLock()
7c351dad
GL
80{
81 if (acquire_lock(&(p_internal->p_mutex)) != 0)
cffee23b 82 return wxMUTEX_BUSY;
b89156b5 83 m_locked++;
cffee23b 84 return wxMUTEX_NO_ERROR;
7c351dad
GL
85}
86
b89156b5 87wxMutexError wxMutex::Unlock()
7c351dad 88{
b89156b5 89 if (m_locked == 0)
cffee23b 90 return wxMUTEX_UNLOCKED;
7c351dad 91 release_lock(&(p_internal->p_mutex));
b89156b5 92 m_locked--;
cffee23b 93 return wxMUTEX_NO_ERROR;
7c351dad
GL
94}
95
b89156b5 96// GL: Don't know how it works on SGI. Wolfram ?
7c351dad 97
ee4f8c2a
JS
98wxCondition::wxCondition() {}
99wxCondition::~wxCondition() {}
7c351dad
GL
100int wxCondition::Wait(wxMutex& WXUNUSED(mutex)) { return 0;}
101int wxCondition::Wait(wxMutex& WXUNUSED(mutex), unsigned long WXUNUSED(sec),
102 unsigned long WXUNUSED(nsec)) { return 0; }
ee4f8c2a
JS
103int wxCondition::Signal() { return 0; }
104int wxCondition::Broadcast() { return 0; }
7c351dad
GL
105
106class
107wxThreadPrivate {
108public:
109 wxThreadPrivate() { thread_id = 0; state = STATE_IDLE; }
110 ~wxThreadPrivate() {}
111 static void SprocStart(void *ptr);
112 static void SignalHandler(int sig);
113public:
114 int state, thread_id;
115 void* exit_status;
116};
117
118void wxThreadPrivate::SprocStart(void *ptr)
119{
120 void* status;
121
122 wxThread *thr = (wxThread *)ptr;
123
124 thr->p_internal->thread_id = getpid();
125 thr->p_internal->exit_status = 0;
126 status = thr->Entry();
127 thr->Exit(status);
128}
129
130void wxThread::Exit(void* status)
131{
132 wxThread* ptr = this;
133 THREAD_SEND_EXIT_MSG(ptr);
134 p_internal->state = STATE_EXITED;
135 p_internal->exit_status = status;
136 _exit(0);
137}
138
b89156b5 139wxThreadError wxThread::Create()
7c351dad
GL
140{
141 if (p_internal->state != STATE_IDLE)
cffee23b 142 return wxTHREAD_RUNNING;
7c351dad
GL
143 p_internal->state = STATE_RUNNING;
144 if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
145 p_internal->state = STATE_IDLE;
cffee23b 146 return wxTHREAD_NO_RESOURCE;
7c351dad 147 }
cffee23b 148 return wxTHREAD_NO_ERROR;
7c351dad
GL
149}
150
c2dd8380 151wxThreadError wxThread::Destroy()
7c351dad
GL
152{
153 if (p_internal->state == STATE_RUNNING)
154 p_internal->state = STATE_CANCELED;
c2dd8380 155
cffee23b 156 return wxTHREAD_NO_ERROR;
c2dd8380
GL
157}
158
159wxThreadError wxThread::Pause()
160{
cffee23b 161 return wxTHREAD_NO_ERROR;
c2dd8380
GL
162}
163
164wxThreadError wxThread::Resume()
165{
cffee23b 166 return wxTHREAD_NO_ERROR;
7c351dad
GL
167}
168
169void *wxThread::Join()
170{
171 if (p_internal->state != STATE_IDLE) {
172 bool do_unlock = wxThread::IsMain();
173 int stat;
174
175 if (do_unlock)
6773ae19 176 wxMainMutex->Unlock();
7c351dad
GL
177 waitpid(p_internal->thread_id, &stat, 0);
178 if (do_unlock)
6773ae19 179 wxMainMutex->Lock();
7c351dad
GL
180 if (!WIFEXITED(stat) && !WIFSIGNALED(stat))
181 return 0;
182 p_internal->state = STATE_IDLE;
183 return p_internal->exit_status;
184 }
185 return 0;
186}
187
ee4f8c2a 188unsigned long wxThread::GetID() const
7c351dad
GL
189{
190 return (unsigned long)p_internal->thread_id;
191}
192
193void wxThread::TestDestroy()
194{
195 if (p_internal->state == STATE_CANCELED) {
196 p_internal->exit_status = 0;
197 _exit(0);
198 }
199}
200
201void wxThread::SetPriority(int prio)
202{
203}
204
ee4f8c2a 205int wxThread::GetPriority() const
7c351dad 206{
ee4f8c2a 207 return 0;
7c351dad
GL
208}
209
c2dd8380 210bool wxThread::IsMain()
7c351dad
GL
211{
212 return (int)getpid() == main_id;
213}
214
c2dd8380
GL
215bool wxThread::IsAlive() const
216{
217 return (p_internal->state == STATE_RUNNING);
218}
219
220bool wxThread::IsRunning() const
221{
222 return (p_internal->state == STATE_RUNNING);
223}
224
7c351dad
GL
225wxThread::wxThread()
226{
227 p_internal = new wxThreadPrivate();
228}
229
230wxThread::~wxThread()
231{
232 Cancel();
233 Join();
234 delete p_internal;
235}
236
237// The default callback just joins the thread and throws away the result.
238void wxThread::OnExit()
239{
240 Join();
241}
242
243// Global initialization
d524867f 244
06cfab17
RR
245class wxThreadModule : public wxModule
246{
247public:
248 virtual bool OnInit();
249 virtual void OnExit();
250
251private:
252 DECLARE_DYNAMIC_CLASS(wxThreadModule)
253};
254
d524867f
RR
255IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
256
257bool wxThreadModule::OnInit()
258{
6773ae19 259 wxMainMutex = new wxMutex();
7c351dad
GL
260 wxThreadGuiInit();
261 p_mainid = (int)getpid();
6773ae19 262 wxMainMutex->Lock();
d524867f
RR
263 return TRUE;
264}
7c351dad 265
d524867f
RR
266void wxThreadModule::OnExit()
267{
6773ae19 268 wxMainMutex->Unlock();
7c351dad 269 wxThreadGuiExit();
6773ae19 270 delete wxMainMutex;
d524867f 271}
7c351dad 272