-/*\r
- * Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * PThreads.cpp\r
- * \r
- * Thread and locking wrappers for POSIX platforms\r
- */\r
-\r
-#include "internal.h"\r
-#include "util/Threads.h"\r
-\r
-#include <ctime>\r
-#include <log4cpp/Category.hh>\r
-\r
-#ifdef HAVE_PTHREAD\r
-# include <pthread.h>\r
-# ifndef HAVE_PTHREAD_RWLOCK_INIT\r
-# include <synch.h>\r
-# endif\r
-#else\r
-# error "This implementation is for POSIX platforms."\r
-#endif\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-namespace xmltooling {\r
-\r
- class XMLTOOL_DLLLOCAL ThreadImpl : public Thread {\r
- pthread_t thread_id;\r
- public:\r
- ThreadImpl(void* (*start_routine)(void*), void* arg);\r
- virtual ~ThreadImpl() {}\r
- \r
- int detach() {\r
- return pthread_detach(thread_id);\r
- }\r
- \r
- int join(void** thread_return) {\r
- return pthread_join(thread_id, thread_return);\r
- }\r
- \r
- int kill(int signo) {\r
- return pthread_kill(thread_id, signo);\r
- }\r
- };\r
- \r
- class XMLTOOL_DLLLOCAL MutexImpl : public Mutex {\r
- pthread_mutex_t mutex;\r
- public:\r
- MutexImpl();\r
- virtual ~MutexImpl() {\r
- pthread_mutex_destroy(&mutex);\r
- }\r
- \r
- int lock() {\r
- return pthread_mutex_lock(&mutex);\r
- }\r
- \r
- int unlock() {\r
- return pthread_mutex_unlock(&mutex);\r
- }\r
- };\r
- \r
- class XMLTOOL_DLLLOCAL CondWaitImpl : public CondWait {\r
- pthread_cond_t cond;\r
- public:\r
- CondWaitImpl();\r
- virtual ~CondWaitImpl() {\r
- pthread_cond_destroy(&cond);\r
- }\r
- \r
- int wait(Mutex* mutex) {\r
- return wait(static_cast<MutexImpl*>(mutex));\r
- }\r
- \r
- int wait(MutexImpl* mutex) {\r
- return pthread_cond_wait(&cond, &(mutex->mutex));\r
- }\r
- \r
- int timedwait(Mutex* mutex, int delay_seconds) {\r
- return timedwait(static_cast<MutexImpl*>(mutex), delay_seconds);\r
- }\r
- \r
- int timedwait(MutexImpl* mutex, int delay_seconds) {\r
- struct timespec ts;\r
- memset(&ts, 0, sizeof(ts));\r
- ts.tv_sec = time(NULL) + delay_seconds;\r
- return pthread_cond_timedwait(&cond, &(mutex->mutex), &ts);\r
- }\r
- \r
- int signal() {\r
- return pthread_cond_signal(&cond);\r
- }\r
- \r
- int broadcast() {\r
- return pthread_cond_broadcast(&cond);\r
- }\r
- };\r
- \r
- class XMLTOOL_DLLLOCAL RWLockImpl : public RWLock {\r
-#ifdef HAVE_PTHREAD_RWLOCK_INIT\r
- pthread_rwlock_t lock;\r
- public:\r
- RWLockImpl();\r
- virtual ~RWLockImpl() {\r
- pthread_rwlock_destroy(&lock);\r
- }\r
- \r
- int rdlock() {\r
- return pthread_rwlock_rdlock(&lock);\r
- }\r
- \r
- int wrlock() {\r
- return pthread_rwlock_wrlock(&lock);\r
- }\r
- \r
- int unlock() {\r
- return pthread_rwlock_unlock(&lock);\r
- }\r
-#else\r
- rwlock_t lock;\r
- public:\r
- RWLockImpl();\r
- virtual ~RWLockImpl() {\r
- rwlock_destroy (&lock);\r
- }\r
- \r
- int rdlock() {\r
- return rw_rdlock(&lock);\r
- }\r
- \r
- int wrlock() {\r
- return rw_wrlock(&lock);\r
- }\r
- \r
- int unlock() {\r
- return rw_unlock(&lock);\r
- }\r
-#endif\r
- };\r
- \r
- class XMLTOOL_DLLLOCAL ThreadKeyImpl : public ThreadKey {\r
- pthread_key_t key;\r
- public:\r
- ThreadKeyImpl(void (*destroy_fcn)(void*));\r
- virtual ~ThreadKeyImpl() {\r
- pthread_key_delete(key);\r
- }\r
- \r
- int setData(void* data) {\r
- return pthread_setspecific(key,data);\r
- }\r
- \r
- void* getData() const {\r
- return pthread_getspecific(key);\r
- }\r
- };\r
-\r
-};\r
-\r
-ThreadImpl::ThreadImpl(void* (*start_routine)(void*), void* arg)\r
-{\r
- int rc=pthread_create(&thread_id, NULL, start_routine, arg);\r
- if (rc) {\r
-#ifdef HAVE_STRERROR_R\r
- char buf[256];\r
- strerror_r(rc,buf,sizeof(buf));\r
- buf[255]=0;\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_create error (%d): %s",rc,buf);\r
-#else\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_create error (%d): %s",rc,strerror(rc));\r
-#endif\r
- throw ThreadingException("Thread creation failed.");\r
- }\r
-}\r
-\r
-MutexImpl::MutexImpl()\r
-{\r
- int rc=pthread_mutex_init(&mutex, NULL);\r
- if (rc) {\r
-#ifdef HAVE_STRERROR_R\r
- char buf[256];\r
- strerror_r(rc,buf,sizeof(buf));\r
- buf[255]=0;\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_mutex_init error (%d): %s",rc,buf);\r
-#else\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_mutex_init error (%d): %s",rc,strerror(rc));\r
-#endif\r
- throw ThreadingException("Mutex creation failed.");\r
- }\r
-}\r
-\r
-CondWaitImpl::CondWaitImpl()\r
-{\r
- int rc=pthread_cond_init(&cond, NULL);\r
- if (rc) {\r
-#ifdef HAVE_STRERROR_R\r
- char buf[256];\r
- strerror_r(rc,buf,sizeof(buf));\r
- buf[255]=0;\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_cond_init error (%d): %s",rc,buf);\r
-#else\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_cond_init error (%d): %s",rc,strerror(rc));\r
-#endif\r
- throw ThreadingException("Condition variable creation failed.");\r
- }\r
-}\r
-\r
-RWLockImpl::RWLockImpl()\r
-{\r
-#ifdef HAVE_PTHREAD_RWLOCK_INIT\r
- int rc=pthread_rwlock_init(&lock, NULL);\r
-#else\r
- int rc=rwlock_init(&lock, USYNC_THREAD, NULL);\r
-#endif\r
- if (rc) {\r
-#ifdef HAVE_STRERROR_R\r
- char buf[256];\r
- strerror_r(rc,buf,sizeof(buf));\r
- buf[255]=0;\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_rwlock_init error (%d): %s",rc,buf);\r
-#else\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_rwlock_init error (%d): %s",rc,strerror(rc));\r
-#endif\r
- throw ThreadingException("Shared lock creation failed.");\r
- }\r
-}\r
-\r
-ThreadKeyImpl::ThreadKeyImpl(void (*destroy_fcn)(void*))\r
-{\r
- int rc=pthread_key_create(&key, destroy_fcn);\r
- if (rc) {\r
-#ifdef HAVE_STRERROR_R\r
- char buf[256];\r
- strerror_r(rc,buf,sizeof(buf));\r
- buf[255]=0;\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_key_create error (%d): %s",rc,buf);\r
-#else\r
- Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_key_create error (%d): %s",rc,strerror(rc));\r
-#endif\r
- throw ThreadingException("Thread key creation failed.");\r
- }\r
-}\r
-\r
-Thread* Thread::create(void* (*start_routine)(void*), void* arg)\r
-{\r
- return new ThreadImpl(start_routine, arg);\r
-}\r
-\r
-void Thread::exit(void* return_val)\r
-{\r
- pthread_exit(return_val);\r
-}\r
- \r
-void Thread::mask_all_signals(void)\r
-{\r
- sigset_t sigmask;\r
- sigfillset(&sigmask);\r
- Thread::mask_signals(SIG_BLOCK, &sigmask, NULL);\r
-}\r
-\r
-int Thread::mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask)\r
-{\r
- return pthread_sigmask(how,newmask,oldmask);\r
-}\r
-\r
-Mutex * Mutex::create()\r
-{\r
- return new MutexImpl();\r
-}\r
-\r
-CondWait * CondWait::create()\r
-{\r
- return new CondWaitImpl();\r
-}\r
-\r
-RWLock * RWLock::create()\r
-{\r
- return new RWLockImpl();\r
-}\r
-\r
-ThreadKey* ThreadKey::create (void (*destroy_fcn)(void*))\r
-{\r
- return new ThreadKeyImpl(destroy_fcn);\r
-}\r
+/*
+ * Copyright 2001-2005 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * PThreads.cpp
+ *
+ * Thread and locking wrappers for POSIX platforms
+ */
+
+#include "internal.h"
+#include "util/Threads.h"
+
+#include <ctime>
+#include <signal.h>
+#include <log4cpp/Category.hh>
+
+#ifdef HAVE_PTHREAD
+# include <pthread.h>
+# ifndef HAVE_PTHREAD_RWLOCK_INIT
+# include <synch.h>
+# endif
+#else
+# error "This implementation is for POSIX platforms."
+#endif
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace xmltooling {
+
+ class XMLTOOL_DLLLOCAL ThreadImpl : public Thread {
+ pthread_t thread_id;
+ public:
+ ThreadImpl(void* (*start_routine)(void*), void* arg);
+ virtual ~ThreadImpl() {}
+
+ int detach() {
+ return pthread_detach(thread_id);
+ }
+
+ int join(void** thread_return) {
+ return pthread_join(thread_id, thread_return);
+ }
+
+ int kill(int signo) {
+ return pthread_kill(thread_id, signo);
+ }
+ };
+
+ class XMLTOOL_DLLLOCAL MutexImpl : public Mutex {
+ pthread_mutex_t mutex;
+ friend class XMLTOOL_DLLLOCAL CondWaitImpl;
+ public:
+ MutexImpl();
+ virtual ~MutexImpl() {
+ pthread_mutex_destroy(&mutex);
+ }
+
+ int lock() {
+ return pthread_mutex_lock(&mutex);
+ }
+
+ int unlock() {
+ return pthread_mutex_unlock(&mutex);
+ }
+ };
+
+ class XMLTOOL_DLLLOCAL CondWaitImpl : public CondWait {
+ pthread_cond_t cond;
+ public:
+ CondWaitImpl();
+ virtual ~CondWaitImpl() {
+ pthread_cond_destroy(&cond);
+ }
+
+ int wait(Mutex* mutex) {
+ return wait(static_cast<MutexImpl*>(mutex));
+ }
+
+ int wait(MutexImpl* mutex) {
+ return pthread_cond_wait(&cond, &(mutex->mutex));
+ }
+
+ int timedwait(Mutex* mutex, int delay_seconds) {
+ return timedwait(static_cast<MutexImpl*>(mutex), delay_seconds);
+ }
+
+ int timedwait(MutexImpl* mutex, int delay_seconds) {
+ struct timespec ts;
+ memset(&ts, 0, sizeof(ts));
+ ts.tv_sec = time(NULL) + delay_seconds;
+ return pthread_cond_timedwait(&cond, &(mutex->mutex), &ts);
+ }
+
+ int signal() {
+ return pthread_cond_signal(&cond);
+ }
+
+ int broadcast() {
+ return pthread_cond_broadcast(&cond);
+ }
+ };
+
+ class XMLTOOL_DLLLOCAL RWLockImpl : public RWLock {
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+ pthread_rwlock_t lock;
+ public:
+ RWLockImpl();
+ virtual ~RWLockImpl() {
+ pthread_rwlock_destroy(&lock);
+ }
+
+ int rdlock() {
+ return pthread_rwlock_rdlock(&lock);
+ }
+
+ int wrlock() {
+ return pthread_rwlock_wrlock(&lock);
+ }
+
+ int unlock() {
+ return pthread_rwlock_unlock(&lock);
+ }
+#else
+ rwlock_t lock;
+ public:
+ RWLockImpl();
+ virtual ~RWLockImpl() {
+ rwlock_destroy (&lock);
+ }
+
+ int rdlock() {
+ return rw_rdlock(&lock);
+ }
+
+ int wrlock() {
+ return rw_wrlock(&lock);
+ }
+
+ int unlock() {
+ return rw_unlock(&lock);
+ }
+#endif
+ };
+
+ class XMLTOOL_DLLLOCAL ThreadKeyImpl : public ThreadKey {
+ pthread_key_t key;
+ public:
+ ThreadKeyImpl(void (*destroy_fcn)(void*));
+ virtual ~ThreadKeyImpl() {
+ pthread_key_delete(key);
+ }
+
+ int setData(void* data) {
+ return pthread_setspecific(key,data);
+ }
+
+ void* getData() const {
+ return pthread_getspecific(key);
+ }
+ };
+
+};
+
+ThreadImpl::ThreadImpl(void* (*start_routine)(void*), void* arg)
+{
+ int rc=pthread_create(&thread_id, NULL, start_routine, arg);
+ if (rc) {
+#ifdef HAVE_STRERROR_R
+ char buf[256];
+ strerror_r(rc,buf,sizeof(buf));
+ buf[255]=0;
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_create error (%d): %s",rc,buf);
+#else
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_create error (%d): %s",rc,strerror(rc));
+#endif
+ throw ThreadingException("Thread creation failed.");
+ }
+}
+
+MutexImpl::MutexImpl()
+{
+ int rc=pthread_mutex_init(&mutex, NULL);
+ if (rc) {
+#ifdef HAVE_STRERROR_R
+ char buf[256];
+ strerror_r(rc,buf,sizeof(buf));
+ buf[255]=0;
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_mutex_init error (%d): %s",rc,buf);
+#else
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_mutex_init error (%d): %s",rc,strerror(rc));
+#endif
+ throw ThreadingException("Mutex creation failed.");
+ }
+}
+
+CondWaitImpl::CondWaitImpl()
+{
+ int rc=pthread_cond_init(&cond, NULL);
+ if (rc) {
+#ifdef HAVE_STRERROR_R
+ char buf[256];
+ strerror_r(rc,buf,sizeof(buf));
+ buf[255]=0;
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_cond_init error (%d): %s",rc,buf);
+#else
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_cond_init error (%d): %s",rc,strerror(rc));
+#endif
+ throw ThreadingException("Condition variable creation failed.");
+ }
+}
+
+RWLockImpl::RWLockImpl()
+{
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+ int rc=pthread_rwlock_init(&lock, NULL);
+#else
+ int rc=rwlock_init(&lock, USYNC_THREAD, NULL);
+#endif
+ if (rc) {
+#ifdef HAVE_STRERROR_R
+ char buf[256];
+ strerror_r(rc,buf,sizeof(buf));
+ buf[255]=0;
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_rwlock_init error (%d): %s",rc,buf);
+#else
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_rwlock_init error (%d): %s",rc,strerror(rc));
+#endif
+ throw ThreadingException("Shared lock creation failed.");
+ }
+}
+
+ThreadKeyImpl::ThreadKeyImpl(void (*destroy_fcn)(void*))
+{
+ int rc=pthread_key_create(&key, destroy_fcn);
+ if (rc) {
+#ifdef HAVE_STRERROR_R
+ char buf[256];
+ strerror_r(rc,buf,sizeof(buf));
+ buf[255]=0;
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_key_create error (%d): %s",rc,buf);
+#else
+ Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("pthread_key_create error (%d): %s",rc,strerror(rc));
+#endif
+ throw ThreadingException("Thread key creation failed.");
+ }
+}
+
+Thread* Thread::create(void* (*start_routine)(void*), void* arg)
+{
+ return new ThreadImpl(start_routine, arg);
+}
+
+void Thread::exit(void* return_val)
+{
+ pthread_exit(return_val);
+}
+
+void Thread::mask_all_signals(void)
+{
+ sigset_t sigmask;
+ sigfillset(&sigmask);
+ Thread::mask_signals(SIG_BLOCK, &sigmask, NULL);
+}
+
+int Thread::mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask)
+{
+ return pthread_sigmask(how,newmask,oldmask);
+}
+
+Mutex * Mutex::create()
+{
+ return new MutexImpl();
+}
+
+CondWait * CondWait::create()
+{
+ return new CondWaitImpl();
+}
+
+RWLock * RWLock::create()
+{
+ return new RWLockImpl();
+}
+
+ThreadKey* ThreadKey::create (void (*destroy_fcn)(void*))
+{
+ return new ThreadKeyImpl(destroy_fcn);
+}