From 13684e6c58ed3f0bd6fd811125e31fc3a37bda21 Mon Sep 17 00:00:00 2001 From: Pixel Date: Thu, 13 Oct 2011 23:52:31 -0700 Subject: Adding a Thread and a Queue class. --- Makefile | 1 + includes/Threads.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Threads.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/Makefile b/Makefile index 9eb4d53..935a54f 100644 --- a/Makefile +++ b/Makefile @@ -148,6 +148,7 @@ TEST_SOURCES = \ test-Sanity.cc \ test-String.cc \ test-Tasks.cc \ +test-Threads.cc \ test-Handles.cc \ LIB = libBalau.a diff --git a/includes/Threads.h b/includes/Threads.h index 5a4ef61..2347a84 100644 --- a/includes/Threads.h +++ b/includes/Threads.h @@ -1,9 +1,13 @@ #pragma once +#include #include namespace Balau { +template +class Queue; + class Lock { public: Lock(); @@ -12,6 +16,51 @@ class Lock { void leave() { pthread_mutex_unlock(&m_lock); } private: pthread_mutex_t m_lock; + template + friend class Queue; +}; + +class ThreadHelper; + +class Thread { + public: + virtual ~Thread(); + void threadStart(); + void * join(); + protected: + Thread() : m_joined(false) { } + virtual void * proc() = 0; + private: + pthread_t m_thread; + bool m_joined; + + friend class ThreadHelper; +}; + +template +class Queue { + public: + Queue() { pthread_cond_init(&m_cond, NULL); } + ~Queue() { pthread_cond_destroy(&m_cond); } + void push(T & t) { + m_lock.enter(); + m_queue.push(t); + pthread_cond_signal(&m_cond); + m_lock.leave(); + } + T pop() { + m_lock.enter(); + if (m_queue.size() == 0) + pthread_cond_wait(&m_cond, &m_lock.m_lock); + T t = m_queue.front(); + m_queue.pop(); + m_lock.leave(); + return t; + } + private: + std::queue m_queue; + Lock m_lock; + pthread_cond_t m_cond; }; }; diff --git a/src/Threads.cc b/src/Threads.cc index fa3f0f3..5f07040 100644 --- a/src/Threads.cc +++ b/src/Threads.cc @@ -1,9 +1,20 @@ #include "Exceptions.h" #include "Threads.h" +#include "Local.h" + +namespace Balau { + +class ThreadHelper { + public: + static void * threadProc(void * arg); +}; + +} Balau::Lock::Lock() { int r; pthread_mutexattr_t attr; + r = pthread_mutexattr_init(&attr); Assert(r == 0); r = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); @@ -11,3 +22,37 @@ Balau::Lock::Lock() { r = pthread_mutex_init(&m_lock, &attr); Assert(r == 0); } + +void * Balau::ThreadHelper::threadProc(void * arg) { + void * tls = g_tlsManager->createTLS(); + g_tlsManager->setTLS(tls); + Balau::Thread * thread = reinterpret_cast(arg); + void * r = thread->proc(); + free(tls); + return r; +} + +Balau::Thread::~Thread() { + join(); +} + +void * Balau::Thread::join() { + void * r = NULL; + if (!m_joined) { + m_joined = true; + pthread_join(m_thread, &r); + } + return r; +} + +void Balau::Thread::threadStart() { + pthread_attr_t attr; + int r; + + r = pthread_attr_init(&attr); + Assert(r == 0); + r = pthread_create(&m_thread, &attr, Balau::ThreadHelper::threadProc, this); + Assert(r == 0); + r = pthread_attr_destroy(&attr); + Assert(r == 0); +} -- cgit v1.2.3