2 * shib-threads.cpp -- an abstraction around Pthreads
4 * Created by: Derek Atkins <derek@ihtfp.com>
6 * $Id: shib-threads.cpp,v 1.5 2003/01/30 15:18:36 warlord Exp $
10 #include "shib-threads.h"
12 #include <log4cpp/Category.hh>
16 #ifndef HAVE_PTHREAD_RWLOCK_INIT
20 #error "You need to create the proper thread implementation"
26 using namespace shibboleth;
27 using namespace log4cpp;
29 // pthread implementation of the Shib Target Threads API
32 // "Private" Implementation
35 class ThreadImpl : public Thread {
37 ThreadImpl(void* (*start_routine)(void*), void* arg);
40 int detach() { return pthread_detach(thread_id); }
41 int join(void** thread_return) { return pthread_join(thread_id, thread_return); }
42 int kill(int signo) { return pthread_kill(thread_id, signo); }
47 class MutexImpl : public Mutex {
50 ~MutexImpl() { pthread_mutex_destroy (&mutex); }
52 int lock() { return pthread_mutex_lock (&mutex); }
53 int unlock() { return pthread_mutex_unlock (&mutex); }
55 pthread_mutex_t mutex;
58 class CondWaitImpl : public CondWait {
61 ~CondWaitImpl() { pthread_cond_destroy (&cond); }
63 int wait(Mutex* mutex) { return wait (dynamic_cast<MutexImpl*>(mutex)); }
64 int wait(MutexImpl* mutex) { return pthread_cond_wait (&cond, &(mutex->mutex)); }
65 int timedwait(Mutex* mutex, int delay_seconds)
66 { return timedwait (dynamic_cast<MutexImpl*>(mutex), delay_seconds); }
67 int timedwait(MutexImpl* mutex, int delay_seconds) {
69 memset (&ts, 0, sizeof(ts));
70 ts.tv_sec = time(NULL) + delay_seconds;
71 return pthread_cond_timedwait (&cond, &(mutex->mutex), &ts);
73 int signal() { return pthread_cond_signal (&cond); }
74 int broadcast() { return pthread_cond_broadcast (&cond); }
79 class RWLockImpl : public RWLock {
81 #ifdef HAVE_PTHREAD_RWLOCK_INIT
83 ~RWLockImpl() { pthread_rwlock_destroy (&lock); }
85 int rdlock() { return pthread_rwlock_rdlock (&lock); }
86 int wrlock() { return pthread_rwlock_wrlock (&lock); }
87 int unlock() { return pthread_rwlock_unlock (&lock); }
89 pthread_rwlock_t lock;
92 ~RWLockImpl() { rwlock_destroy (&lock); }
94 int rdlock() { return rw_rdlock (&lock); }
95 int wrlock() { return rw_wrlock (&lock); }
96 int unlock() { return rw_unlock (&lock); }
102 class ThreadKeyImpl : public ThreadKey {
104 ThreadKeyImpl(void (*destroy_fcn)(void*));
105 ~ThreadKeyImpl() { pthread_key_delete (key); }
107 int setData(void* data) { return pthread_setspecific (key,data); }
108 void* getData() { return pthread_getspecific (key); }
114 // Constructor Implementation follows...
117 ThreadImpl::ThreadImpl(void* (*start_routine)(void*), void* arg)
119 int rc=pthread_create(&thread_id, NULL, start_routine, arg);
121 #ifdef HAVE_STRERROR_R
123 strerror_r(rc,buf,sizeof(buf));
125 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_create error (%d): %s",rc,buf);
127 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_create error (%d): %s",rc,strerror(rc));
133 MutexImpl::MutexImpl()
135 int rc=pthread_mutex_init(&mutex, NULL);
137 #ifdef HAVE_STRERROR_R
139 strerror_r(rc,buf,sizeof(buf));
141 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_mutex_init error (%d): %s",rc,buf);
143 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_mutex_init error (%d): %s",rc,strerror(rc));
149 CondWaitImpl::CondWaitImpl()
151 int rc=pthread_cond_init(&cond, NULL);
153 #ifdef HAVE_STRERROR_R
155 strerror_r(rc,buf,sizeof(buf));
157 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_cond_init error (%d): %s",rc,buf);
159 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_cond_init error (%d): %s",rc,strerror(rc));
165 RWLockImpl::RWLockImpl()
167 #ifdef HAVE_PTHREAD_RWLOCK_INIT
168 int rc=pthread_rwlock_init(&lock, NULL);
170 int rc=rwlock_init(&lock, USYNC_THREAD, NULL);
173 #ifdef HAVE_STRERROR_R
175 strerror_r(rc,buf,sizeof(buf));
177 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_rwlock_init error (%d): %s",rc,buf);
179 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_rwlock_init error (%d): %s",rc,strerror(rc));
185 ThreadKeyImpl::ThreadKeyImpl(void (*destroy_fcn)(void*))
187 int rc=pthread_key_create(&key, destroy_fcn);
189 #ifdef HAVE_STRERROR_R
191 strerror_r(rc,buf,sizeof(buf));
193 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_key_create error (%d): %s",rc,buf);
195 Category::getInstance(SHIB_LOGCAT".threads").error("pthread_key_create error (%d): %s",rc,strerror(rc));
202 // public "static" creation functions
205 Thread* Thread::create(void* (*start_routine)(void*), void* arg)
207 return new ThreadImpl(start_routine, arg);
210 void Thread::exit(void* return_val)
212 pthread_exit (return_val);
215 void Thread::mask_all_signals(void)
218 sigfillset(&sigmask);
219 Thread::mask_signals(SIG_BLOCK, &sigmask, NULL);
222 int Thread::mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask)
224 return pthread_sigmask(how,newmask,oldmask);
227 Mutex * Mutex::create()
229 return new MutexImpl();
232 CondWait * CondWait::create()
234 return new CondWaitImpl();
237 RWLock * RWLock::create()
239 return new RWLockImpl();
242 ThreadKey* ThreadKey::create (void (*destroy_fcn)(void*))
244 return new ThreadKeyImpl(destroy_fcn);