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