From 79deafe642561936ebb3bbcf585f2c6f26b456d3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 14 May 2012 04:30:00 +0000 Subject: Remove Thread context stuff and add a thread-specific variable class, ThreadVar, which can be used for this and many other things. ClientBroadcaster => Broadcaster. git-svn-id: http://svn.drobilla.net/lad/trunk/raul@4405 a436a847-0d15-0410-975c-d299462d15a1 --- NEWS | 2 ++ raul/Thread.hpp | 15 ++++-------- raul/ThreadVar.hpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Thread.cpp | 32 +++++++------------------ 4 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 raul/ThreadVar.hpp diff --git a/NEWS b/NEWS index 5237857..d3a6cde 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ raul (9999) unstable; * Add INSTALL file * Improve RingBuffer * Improve test suite + * Remove Thread context stuff and add a thread-specific variable class, + ThreadVar, which can be used for this and many other things * Update license to GPL3+ -- David Robillard diff --git a/raul/Thread.hpp b/raul/Thread.hpp index 9e184d8..9b61048 100644 --- a/raul/Thread.hpp +++ b/raul/Thread.hpp @@ -17,7 +17,6 @@ #ifndef RAUL_THREAD_HPP #define RAUL_THREAD_HPP -#include #include #include "raul/Noncopyable.hpp" @@ -50,7 +49,7 @@ public: * If the calling thread does not yet have a Thread object associated with * it, one will be created. */ - static Thread& get(); + static Thread& get(const std::string& name=""); virtual void start(); virtual void stop(); @@ -62,9 +61,6 @@ public: const std::string& name() const { return _name; } void set_name(const std::string& name) { _name = name; } - bool is_context(unsigned context) const { return _contexts.find(context) != _contexts.end(); } - void set_context(unsigned context) { _contexts.insert(context); } - protected: explicit Thread(const std::string& name=""); Thread(pthread_t thread, const std::string& name=""); @@ -84,11 +80,10 @@ protected: private: static void* _static_run(void* me); - ThreadImpl* _impl; - std::set _contexts; - std::string _name; - bool _thread_exists; - bool _own_thread; + ThreadImpl* _impl; + std::string _name; + bool _thread_exists; + bool _own_thread; }; } // namespace Raul diff --git a/raul/ThreadVar.hpp b/raul/ThreadVar.hpp new file mode 100644 index 0000000..54e0d4e --- /dev/null +++ b/raul/ThreadVar.hpp @@ -0,0 +1,70 @@ +/* + This file is part of Raul. + Copyright 2007-2012 David Robillard + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see . +*/ + +#ifndef RAUL_THREADVAR_HPP +#define RAUL_THREADVAR_HPP + +#include +#include + +namespace Raul { + +struct ThreadVarImpl; + +/** Thread-specific variable. + */ +template +class ThreadVar +{ +public: + ThreadVar(const T& default_value) + : _default_value(default_value) + { + pthread_key_create(&_key, free); + } + + ~ThreadVar() { + pthread_key_delete(_key); + } + + ThreadVar& operator=(const T& value) { + T* val = (T*)pthread_getspecific(_key); + if (val) { + *val = value; + } else { + val = (T*)malloc(sizeof(value)); + *val = value; + pthread_setspecific(_key, val); + } + return *this; + } + + operator T() const { + T* val = (T*)pthread_getspecific(_key); + return val ? *val : _default_value; + } + +private: + ThreadVar(const ThreadVar& noncopyable); + ThreadVar& operator=(const ThreadVar& noncopyable); + + const T _default_value; + pthread_key_t _key; +}; + +} // namespace Raul + +#endif // RAUL_THREADVAR_HPP diff --git a/src/Thread.cpp b/src/Thread.cpp index 353e9b7..4a3e7bf 100644 --- a/src/Thread.cpp +++ b/src/Thread.cpp @@ -21,6 +21,7 @@ #include "raul/log.hpp" #include "raul/Thread.hpp" +#include "raul/ThreadVar.hpp" #define LOG(s) (s("[")(_name)("] ")) @@ -32,12 +33,7 @@ struct ThreadImpl { pthread_t pthread; }; -static pthread_once_t s_thread_key_once = PTHREAD_ONCE_INIT; -static pthread_key_t s_thread_key; - -static void thread_key_alloc() { - pthread_key_create(&s_thread_key, NULL); -} +static ThreadVar self(NULL); Thread::Thread(const std::string& name) : _exit_flag(false) @@ -46,8 +42,6 @@ Thread::Thread(const std::string& name) , _thread_exists(false) , _own_thread(true) { - pthread_once(&s_thread_key_once, thread_key_alloc); - pthread_setspecific(s_thread_key, this); } /** Must be called from thread */ @@ -59,8 +53,6 @@ Thread::Thread(pthread_t thread, const std::string& name) , _own_thread(false) { _impl->pthread = thread; - pthread_once(&s_thread_key_once, thread_key_alloc); - pthread_setspecific(s_thread_key, this); } Thread::~Thread() @@ -69,29 +61,21 @@ Thread::~Thread() delete _impl; } -Thread* -Thread::create_for_this_thread(const std::string& name) -{ - return new Thread(pthread_self(), name); -} - Thread& -Thread::get() +Thread::get(const std::string& name) { - pthread_once(&s_thread_key_once, thread_key_alloc); - Thread* this_thread = reinterpret_cast( - pthread_getspecific(s_thread_key)); - if (!this_thread) - this_thread = create_for_this_thread(""); + if (!self) { + self = new Thread(pthread_self(), name); + } - return *this_thread; + return *self; } void* Thread::_static_run(void* thread) { Thread* me = static_cast(thread); - pthread_setspecific(s_thread_key, thread); + self = me; me->_run(); me->_thread_exists = false; return NULL; -- cgit v1.2.1