const/void changes in thread, tabctrl and wave files; wxTabCtrl::InsertItem
[wxWidgets.git] / src / gtk1 / 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
22 enum thread_state {
23 STATE_IDLE = 0,
24 STATE_RUNNING,
25 STATE_CANCELED,
26 STATE_EXITED
27 };
28
29 /////////////////////////////////////////////////////////////////////////////
30 // Static variables
31 /////////////////////////////////////////////////////////////////////////////
32
33 static int p_mainid;
34 wxMutex wxMainMutex;
35
36 #include "threadgui.inc"
37
38 /////////////////////////////////////////////////////////////////////////////
39 // Unix implementations (SGI threads)
40 /////////////////////////////////////////////////////////////////////////////
41
42 class wxMutexInternal {
43 public:
44 abilock_t p_mutex;
45 };
46
47 wxMutex::wxMutex()
48 {
49 p_internal = new wxMutexInternal;
50 init_lock(&(p_internal->p_mutex));
51 }
52
53 wxMutex::~wxMutex()
54 {
55 }
56
57 wxMutex::MutexError wxMutex::Lock()
58 {
59 spin_lock(&(p_internal->p_mutex));
60 return NO_ERROR;
61 }
62
63 wxMutex::MutexError wxMutex::TryLock()
64 {
65 if (acquire_lock(&(p_internal->p_mutex)) != 0)
66 return BUSY;
67 return NO_ERROR;
68 }
69
70 wxMutex::MutexError wxMutex::Unlock()
71 {
72 release_lock(&(p_internal->p_mutex));
73 return NO_ERROR;
74 }
75
76 // GLH: Don't now how it works on SGI. Wolfram ?
77
78 wxCondition::wxCondition() {}
79 wxCondition::~wxCondition() {}
80 int wxCondition::Wait(wxMutex& WXUNUSED(mutex)) { return 0;}
81 int wxCondition::Wait(wxMutex& WXUNUSED(mutex), unsigned long WXUNUSED(sec),
82 unsigned long WXUNUSED(nsec)) { return 0; }
83 int wxCondition::Signal() { return 0; }
84 int wxCondition::Broadcast() { return 0; }
85
86 class
87 wxThreadPrivate {
88 public:
89 wxThreadPrivate() { thread_id = 0; state = STATE_IDLE; }
90 ~wxThreadPrivate() {}
91 static void SprocStart(void *ptr);
92 static void SignalHandler(int sig);
93 public:
94 int state, thread_id;
95 void* exit_status;
96 };
97
98 void wxThreadPrivate::SprocStart(void *ptr)
99 {
100 void* status;
101
102 wxThread *thr = (wxThread *)ptr;
103
104 thr->p_internal->thread_id = getpid();
105 thr->p_internal->exit_status = 0;
106 status = thr->Entry();
107 thr->Exit(status);
108 }
109
110 void wxThread::Exit(void* status)
111 {
112 wxThread* ptr = this;
113 THREAD_SEND_EXIT_MSG(ptr);
114 p_internal->state = STATE_EXITED;
115 p_internal->exit_status = status;
116 _exit(0);
117 }
118
119 wxThread::ThreadError wxThread::Create()
120 {
121 if (p_internal->state != STATE_IDLE)
122 return RUNNING;
123 p_internal->state = STATE_RUNNING;
124 if (sproc(p_internal->SprocStart, PR_SALL, this) < 0) {
125 p_internal->state = STATE_IDLE;
126 return NO_RESOURCE;
127 }
128 return NO_ERROR;
129 }
130
131 void wxThread::Destroy()
132 {
133 if (p_internal->state == STATE_RUNNING)
134 p_internal->state = STATE_CANCELED;
135 }
136
137 void *wxThread::Join()
138 {
139 if (p_internal->state != STATE_IDLE) {
140 bool do_unlock = wxThread::IsMain();
141 int stat;
142
143 if (do_unlock)
144 wxMainMutex.Unlock();
145 waitpid(p_internal->thread_id, &stat, 0);
146 if (do_unlock)
147 wxMainMutex.Lock();
148 if (!WIFEXITED(stat) && !WIFSIGNALED(stat))
149 return 0;
150 p_internal->state = STATE_IDLE;
151 return p_internal->exit_status;
152 }
153 return 0;
154 }
155
156 unsigned long wxThread::GetID() const
157 {
158 return (unsigned long)p_internal->thread_id;
159 }
160
161 void wxThread::TestDestroy()
162 {
163 if (p_internal->state == STATE_CANCELED) {
164 p_internal->exit_status = 0;
165 _exit(0);
166 }
167 }
168
169 void wxThread::SetPriority(int prio)
170 {
171 }
172
173 int wxThread::GetPriority() const
174 {
175 return 0;
176 }
177
178 bool wxThreadIsMain()
179 {
180 return (int)getpid() == main_id;
181 }
182
183 wxThread::wxThread()
184 {
185 p_internal = new wxThreadPrivate();
186 }
187
188 wxThread::~wxThread()
189 {
190 Cancel();
191 Join();
192 delete p_internal;
193 }
194
195 // The default callback just joins the thread and throws away the result.
196 void wxThread::OnExit()
197 {
198 Join();
199 }
200
201 // Global initialization
202 class wxThreadModule : public wxModule {
203 DECLARE_DYNAMIC_CLASS(wxThreadModule)
204 public:
205 virtual bool OnInit() {
206 wxThreadGuiInit();
207 p_mainid = (int)getpid();
208 wxMainMutex.Lock();
209 }
210
211 virtual void OnExit() {
212 wxMainMutex.Unlock();
213 wxThreadGuiExit();
214 }
215 };
216
217 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)