namespace os {
- class recursive_mutex
+ /**
+ * Base class for mutex and recursive_mutex.
+ */
+ class _base_mutex
{
public:
#ifdef _WIN32
typedef pthread_mutex_t native_handle_type;
#endif
- recursive_mutex(void) {
+ _base_mutex(void) {
#ifdef _WIN32
InitializeCriticalSection(&_native_handle);
#else
#endif
}
- ~recursive_mutex() {
+ ~_base_mutex() {
#ifdef _WIN32
DeleteCriticalSection(&_native_handle);
#else
#endif
}
- private:
+ native_handle_type & native_handle() {
+ return _native_handle;
+ }
+
+ protected:
native_handle_type _native_handle;
};
+ /**
+ * Same interface as std::mutex.
+ */
+ class mutex : public _base_mutex
+ {
+ public:
+ inline
+ mutex(void) {
+#ifdef _WIN32
+ InitializeCriticalSection(&_native_handle);
+#else
+ pthread_mutex_init(&_native_handle, NULL);
+#endif
+ }
+ };
+
+
+ /**
+ * Same interface as std::recursive_mutex.
+ */
+ class recursive_mutex : public _base_mutex
+ {
+ public:
+ inline
+ recursive_mutex(void) {
+#ifdef _WIN32
+ InitializeCriticalSection(&_native_handle);
+#else
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&_native_handle, &attr);
+ pthread_mutexattr_destroy(&attr);
+#endif
+ }
+ };
+
+
+ /**
+ * Same interface as boost::thread_specific_ptr.
+ */
template <typename T>
class thread_specific_ptr
{
}
};
+
} /* namespace os */
#endif /* _OS_THREAD_HPP_ */
*/
int WorkQueue::run_tasks(void)
{
- pthread_mutex_lock(&lock);
+ lock.lock();
while (work_queue.empty() && !exit_workqueue)
- pthread_cond_wait(&wake_cond, &lock);
+ pthread_cond_wait(&wake_cond, &lock.native_handle());
if (exit_workqueue) {
- pthread_mutex_unlock(&lock);
+ lock.unlock();
return -1;
}
std::swap(work_queue, batch);
busy = true;
- pthread_mutex_unlock(&lock);
+ lock.unlock();
assert(!batch.empty());
while (!batch.empty()) {
delete task;
}
- pthread_mutex_lock(&lock);
+ lock.lock();
busy = false;
pthread_cond_signal(&complete_cond);
- pthread_mutex_unlock(&lock);
+ lock.unlock();
return 0;
}
void WorkQueue::queue_work(WorkQueueWork *task)
{
- pthread_mutex_lock(&lock);
+ lock.lock();
work_queue.push(task);
wake_up_thread();
- pthread_mutex_unlock(&lock);
+ lock.unlock();
}
void WorkQueue::flush(void)
{
- pthread_mutex_lock(&lock);
+ lock.lock();
while (!work_queue.empty() || busy)
- pthread_cond_wait(&complete_cond, &lock);
- pthread_mutex_unlock(&lock);
+ pthread_cond_wait(&complete_cond, &lock.native_handle());
+ lock.unlock();
}
void WorkQueue::thread_entry(void)
void WorkQueue::destroy(void)
{
- pthread_mutex_lock(&lock);
+ lock.lock();
exit_workqueue = true;
wake_up_thread();
- pthread_mutex_unlock(&lock);
+ lock.unlock();
}
extern "C"
pthread_cond_init(&wake_cond, NULL);
pthread_cond_init(&complete_cond, NULL);
- pthread_mutex_init(&lock, NULL);
err = pthread_create(&handle, NULL, WorkQueue__entry_thunk, this);
assert(!err);
}