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