2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
27 * $TOG: Threads.C /main/5 1997/09/03 17:26:05 mgreess $
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special
32 * restrictions in a confidential disclosure agreement bertween
33 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
35 * Sun's specific written approval. This documment and all copies
36 * and derivative works thereof must be returned or destroyed at
39 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
47 #if defined(I_HAVE_SELECT_H)
48 #include <sys/select.h>
51 #if defined(POSIX_THREADS)
56 #include <DtMail/DtMail.hh>
57 #include <DtMail/Threads.hh>
58 #include <DtMail/IO.hh>
60 static long DUMMY_MUTEX;
65 #if defined(POSIX_THREADS)
66 mutex_t *mutex = (mutex_t *)malloc(sizeof(mutex_t));
68 mutex_init(mutex, USYNC_THREAD, NULL);
76 MutexDestroy(void * mutex)
78 #if defined(POSIX_THREADS)
79 mutex_destroy((mutex_t *)mutex);
88 MutexLock::MutexLock(void * mutex)
90 #if defined(POSIX_THREADS)
91 mutex_lock((mutex_t *)mutex);
97 MutexLock::~MutexLock(void)
99 #if defined(POSIX_THREADS)
101 mutex_unlock((mutex_t *)_mutex);
108 MutexLock::unlock(void)
110 #if defined(POSIX_THREADS)
112 mutex_unlock((mutex_t *)_mutex);
120 MutexLock::unlock_and_destroy(void)
122 #if defined(POSIX_THREADS)
124 mutex_unlock((mutex_t *)_mutex);
127 MutexDestroy(_mutex);
131 SafeScalarImpl::SafeScalarImpl(void)
133 _mutex = MutexInit();
137 SafeScalarImpl::~SafeScalarImpl(void)
139 MutexDestroy(_mutex);
143 SafeScalarImpl::operator = (const long val)
145 MutexLock lock_scope(_mutex);
152 SafeScalarImpl::operator += (const long val)
154 MutexLock lock_scope(_mutex);
161 SafeScalarImpl::operator -= (const long val)
163 MutexLock lock_scope(_mutex);
170 SafeScalarImpl::operator *= (const long val)
172 MutexLock lock_scope(_mutex);
179 SafeScalarImpl::operator /= (const long val)
181 MutexLock lock_scope(_mutex);
188 SafeScalarImpl::operator == (const long val)
190 MutexLock lock_scope(_mutex);
192 return(_value == val);
196 SafeScalarImpl::operator <= (const long val)
198 MutexLock lock_scope(_mutex);
200 return(_value <= val);
204 SafeScalarImpl::operator < (const long val)
206 MutexLock lock_scope(_mutex);
208 return(_value < val);
212 SafeScalarImpl::operator >= (const long val)
214 MutexLock lock_scope(_mutex);
216 return(_value >= val);
220 SafeScalarImpl::operator > (const long val)
222 MutexLock lock_scope(_mutex);
224 return(_value > val);
228 SafeScalarImpl::operator != (const long val)
230 MutexLock lock_scope(_mutex);
232 return(_value != val);
235 SafeScalarImpl::operator long(void)
237 MutexLock lock_scope(_mutex);
242 Condition::Condition(void)
244 _mutex = MutexInit();
246 #if defined(POSIX_THREADS)
247 _condition = malloc(sizeof(cond_t));
248 cond_init((cond_t *)_condition, USYNC_THREAD, NULL);
253 Condition::~Condition(void)
255 MutexDestroy(_mutex);
257 #if defined(POSIX_THREADS)
258 cond_destroy((cond_t *)_condition);
265 Condition::setTrue(void)
267 MutexLock lock_scope(_mutex);
271 #if defined(POSIX_THREADS)
272 cond_broadcast((cond_t *)_condition); // Wake all sleepers.
278 Condition::setFalse(void)
280 MutexLock lock_scope(_mutex);
284 #if defined(POSIX_THREADS)
285 cond_broadcast((cond_t *)_condition); // Wake all sleepers.
290 Condition::operator=(int new_state)
292 MutexLock lock_scope(_mutex);
296 #if defined(POSIX_THREADS)
297 cond_broadcast((cond_t *)_condition); // Wake all sleepers.
304 Condition::operator+=(int new_state)
306 MutexLock lock_scope(_mutex);
310 #if defined(POSIX_THREADS)
311 cond_broadcast((cond_t *)_condition); // Wake all sleepers.
317 Condition::operator int(void)
323 Condition::state(void)
325 MutexLock lock_scope(_mutex);
327 int save_state = _state;
333 Condition::wait(void)
335 // Wait for anything to change.
337 #if defined(POSIX_THREADS)
338 MutexLock lock_scope(_mutex);
341 abstime.tv_sec = time(NULL) + 1; // Wait for 1 second.
344 cond_timedwait((cond_t *)_condition, (mutex_t *)_mutex, &abstime);
351 Condition::waitTrue(void)
353 // Wait for the condition to become true.
355 #if defined(POSIX_THREADS)
356 MutexLock lock_scope(_mutex);
359 cond_wait((cond_t *)_condition, (mutex_t *)_mutex);
362 _state = 1; // Must set of single threaded apps.
370 Condition::waitFalse(void)
372 // Wait for the condition to become true.
374 #if defined(POSIX_THREADS)
375 MutexLock lock_scope(_mutex);
378 cond_wait((cond_t *)_condition, (mutex_t *)_mutex);
388 Condition::waitFor(int new_state)
390 // Wait for the condition to become true.
392 #if defined(POSIX_THREADS)
393 MutexLock lock_scope(_mutex);
395 while(_state != new_state) {
396 cond_wait((cond_t *)_condition, (mutex_t *)_mutex);
404 Condition::waitGT(int new_state)
406 // Wait for the condition to become true.
408 #if defined(POSIX_THREADS)
409 MutexLock lock_scope(_mutex);
411 while(_state > new_state) {
412 cond_wait((cond_t *)_condition, (mutex_t *)_mutex);
420 Condition::waitLT(int new_state)
422 // Wait for the condition to become true.
424 #if defined(POSIX_THREADS)
425 MutexLock lock_scope(_mutex);
427 while(_state < new_state) {
428 cond_wait((cond_t *)_condition, (mutex_t *)_mutex);
436 Condition::waitProcStatus(void)
438 // Wait for the condition to become true.
440 #if defined(POSIX_THREADS)
441 MutexLock lock_scope(_mutex);
444 cond_wait((cond_t *)_condition, (mutex_t *)_mutex);
452 #endif /* DEAD_WOOD */
456 #if defined(POSIX_THREADS)
457 ThreadEntryPoint entry, void * client_data)
461 thr_create(NULL, 0, entry, client_data, THR_BOUND | THR_NEW_LWP, &id);
467 ThreadEntryPoint, void*)
476 #if defined(POSIX_THREADS)
486 #if defined(POSIX_THREADS)
487 Thread thread, const int prio)
489 thr_setprio((thread_t)thread, prio);
499 #if defined(POSIX_THREADS)
500 Thread thread, const int sig)
502 thr_kill((thread_t)thread, sig);
512 #if defined(POSIX_THREADS)
515 thr_exit((void *)status);
525 #if defined(POSIX_THREADS)
528 thr_join((thread_t)thread, NULL, NULL);
536 // The ThreadSleep function mimics the behavior of sleep(3), but
537 // uses select to prevent SIGALRM from being sent. This is bad
538 // on MT because often the main thread gets the signal and exits.
541 ThreadSleep(time_t secs)
543 time_t now = time(NULL);
547 interval.tv_sec = secs;
548 interval.tv_usec = 0;
550 select(0, NULL, NULL, NULL, &interval);
552 time_t slept = time(NULL) - now;
554 return(secs - slept);
561 void * operator new(size_t size)
563 return(malloc(size));
566 void operator delete(void * ptr)