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