]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/threadsgi.cpp
Fix memory leak when a spacer is added, and crash when a window is added before wxSiz...
[wxWidgets.git] / src / gtk1 / threadsgi.cpp
... / ...
CommitLineData
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)
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
12#pragma implementation "thread.h"
13#endif
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#include "wx/thread.h"
19#include <stdio.h>
20#include <unistd.h>
21
22#include <signal.h>
23#include <sys/wait.h>
24#include <sys/prctl.h>
25#include "wx/module.h"
26#include "wx/utils.h"
27#include "wx/log.h"
28
29#include "gdk/gdk.h"
30#include "gtk/gtk.h"
31
32enum thread_state
33{
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;
45wxMutex *wxMainMutex;
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{
60 m_locked = 0;
61 p_internal = new wxMutexInternal;
62 init_lock(&(p_internal->p_mutex));
63}
64
65wxMutex::~wxMutex()
66{
67 if (m_locked > 0)
68 wxLogDebug( "wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked );
69 delete p_internal;
70}
71
72wxMutexError wxMutex::Lock()
73{
74 spin_lock(&(p_internal->p_mutex));
75 m_locked++;
76 return wxMUTEX_NO_ERROR;
77}
78
79wxMutexError wxMutex::TryLock()
80{
81 if (acquire_lock(&(p_internal->p_mutex)) != 0)
82 return wxMUTEX_BUSY;
83 m_locked++;
84 return wxMUTEX_NO_ERROR;
85}
86
87wxMutexError wxMutex::Unlock()
88{
89 if (m_locked == 0)
90 return wxMUTEX_UNLOCKED;
91 release_lock(&(p_internal->p_mutex));
92 m_locked--;
93 return wxMUTEX_NO_ERROR;
94}
95
96// GL: Don't know how it works on SGI. Wolfram ?
97
98wxCondition::wxCondition() {}
99wxCondition::~wxCondition() {}
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; }
103int wxCondition::Signal() { return 0; }
104int wxCondition::Broadcast() { return 0; }
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
139wxThreadError wxThread::Create()
140{
141 if (p_internal->state != STATE_IDLE)
142 return wxTHREAD_RUNNING;
143 p_internal->state = STATE_RUNNING;
144 if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
145 p_internal->state = STATE_IDLE;
146 return wxTHREAD_NO_RESOURCE;
147 }
148 return wxTHREAD_NO_ERROR;
149}
150
151wxThreadError wxThread::Destroy()
152{
153 if (p_internal->state == STATE_RUNNING)
154 p_internal->state = STATE_CANCELED;
155
156 return wxTHREAD_NO_ERROR;
157}
158
159wxThreadError wxThread::Pause()
160{
161 return wxTHREAD_NO_ERROR;
162}
163
164wxThreadError wxThread::Resume()
165{
166 return wxTHREAD_NO_ERROR;
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)
176 wxMainMutex->Unlock();
177 waitpid(p_internal->thread_id, &stat, 0);
178 if (do_unlock)
179 wxMainMutex->Lock();
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
188unsigned long wxThread::GetID() const
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
205int wxThread::GetPriority() const
206{
207 return 0;
208}
209
210bool wxThread::IsMain()
211{
212 return (int)getpid() == main_id;
213}
214
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
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
244
245class wxThreadModule : public wxModule
246{
247public:
248 virtual bool OnInit();
249 virtual void OnExit();
250
251private:
252 DECLARE_DYNAMIC_CLASS(wxThreadModule)
253};
254
255IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
256
257bool wxThreadModule::OnInit()
258{
259 wxMainMutex = new wxMutex();
260 wxThreadGuiInit();
261 p_mainid = (int)getpid();
262 wxMainMutex->Lock();
263 return TRUE;
264}
265
266void wxThreadModule::OnExit()
267{
268 wxMainMutex->Unlock();
269 wxThreadGuiExit();
270 delete wxMainMutex;
271}
272