diff --git a/src/thread/thread.h b/src/thread/thread.h index 64713e3d..f9e1e871 100644 --- a/src/thread/thread.h +++ b/src/thread/thread.h @@ -31,10 +31,10 @@ public: Mutex() : MutexBase() {} }; -class Condition : public ConditionBase +class Queue : public QueueBase { public: - Condition() : ConditionBase() {} + Queue() : QueueBase() {} }; class Thread : ThreadBase diff --git a/src/thread/threadbase.h b/src/thread/threadbase.h index 9921d55e..a3208403 100644 --- a/src/thread/threadbase.h +++ b/src/thread/threadbase.h @@ -17,6 +17,7 @@ #define __LOL_THREADBASE_H__ #if defined __linux__ || defined __native_client__ +# include # include #elif defined _WIN32 # include @@ -74,18 +75,21 @@ private: #endif }; -class ConditionBase +class QueueBase { public: - ConditionBase() + QueueBase() { #if defined __linux__ || defined __native_client__ + memset(m_values, 0, sizeof(m_values)); + m_waiting = 0; + m_size = 0; pthread_mutex_init(&m_mutex, NULL); pthread_cond_init(&m_cond, NULL); #endif } - ~ConditionBase() + ~QueueBase() { #if defined __linux__ || defined __native_client__ pthread_cond_destroy(&m_cond); @@ -93,36 +97,43 @@ public: #endif } - void Acquire() + void Push(int value) { #if defined __linux__ || defined __native_client__ pthread_mutex_lock(&m_mutex); -#endif - } - - void Release() - { -#if defined __linux__ || defined __native_client__ + m_values[m_size] = value; + m_size++; + if (m_waiting) + pthread_cond_signal(&m_cond); pthread_mutex_unlock(&m_mutex); #endif } - void Wait() - { -#if defined __linux__ || defined __native_client__ - pthread_cond_wait(&m_cond, &m_mutex); -#endif - } - - void Notify() + int Pop() { #if defined __linux__ || defined __native_client__ - pthread_cond_signal(&m_cond); + pthread_mutex_lock(&m_mutex); + /* Loop until there is something in the queue. Be careful, we + * could get woken up but another thread may have eaten the + * message in the meantime. */ + while (!m_size) + { + m_waiting++; + pthread_cond_wait(&m_cond, &m_mutex); + m_waiting--; + } + m_size--; + int ret = m_values[0]; + memmove(m_values, m_values + 1, m_size * sizeof(m_values[0])); + pthread_mutex_unlock(&m_mutex); + return ret; #endif } private: #if defined __linux__ || defined __native_client__ + int m_values[100]; + size_t m_waiting, m_size; pthread_mutex_t m_mutex; pthread_cond_t m_cond; #endif @@ -134,9 +145,14 @@ public: ThreadBase(void *(*fn)(void *), void *data) { #if defined __linux__ || defined __native_client__ - pthread_create(&m_thread, NULL, fn, data); + /* Set the joinable attribute for systems who don't play nice */ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_create(&m_thread, &attr, fn, data); #elif defined _WIN32 - m_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fn, data, 0, &m_tid); + m_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fn, + data, 0, &m_tid); #endif }