mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-12 12:02:54 +00:00
use thread_specific_ptr
This commit is contained in:
@@ -7,11 +7,9 @@
|
||||
#ifndef BOOST_FIBERS_THREAD_LOCAL_PTR_H
|
||||
#define BOOST_FIBERS_THREAD_LOCAL_PTR_H
|
||||
|
||||
#include <pthread.h> // pthread_key_create, pthread_[gs]etspecific
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
|
||||
@@ -22,102 +20,9 @@
|
||||
namespace boost {
|
||||
namespace fibers {
|
||||
|
||||
# if ! (defined(__APPLE__) && defined(BOOST_HAS_PTHREADS))
|
||||
template< typename T >
|
||||
class thread_local_ptr : private noncopyable
|
||||
{
|
||||
private:
|
||||
static void cleanup_function( void * vp)
|
||||
{
|
||||
thread_local_ptr< T > * p = static_cast< thread_local_ptr< T > * >( vp);
|
||||
BOOST_ASSERT( 0 != p);
|
||||
delete p->t_;
|
||||
p->t_ = 0;
|
||||
}
|
||||
|
||||
static __thread T * t_;
|
||||
|
||||
pthread_key_t key_;
|
||||
|
||||
public:
|
||||
thread_local_ptr() BOOST_NOEXCEPT :
|
||||
key_()
|
||||
{ ::pthread_key_create( & key_, & thread_local_ptr::cleanup_function); }
|
||||
|
||||
~thread_local_ptr()
|
||||
{ if ( 0 != t_) cleanup_function( t_); } // required for single-threaded apps
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL();
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{ return t_; }
|
||||
|
||||
bool operator!() const BOOST_NOEXCEPT
|
||||
{ return ! get(); }
|
||||
|
||||
bool operator==( thread_local_ptr const& other) BOOST_NOEXCEPT
|
||||
{ return this->get() == other.get(); }
|
||||
|
||||
bool operator!=( thread_local_ptr const& other) BOOST_NOEXCEPT
|
||||
{ return ! ( * this == other); }
|
||||
|
||||
void reset( T * t) BOOST_NOEXCEPT
|
||||
{
|
||||
t_ = t;
|
||||
::pthread_setspecific( key_, this);
|
||||
}
|
||||
};
|
||||
template< typename T >
|
||||
__thread T * thread_local_ptr< T >::t_ = 0;
|
||||
# else
|
||||
template< typename T >
|
||||
class thread_local_ptr : private noncopyable
|
||||
{
|
||||
private:
|
||||
static void cleanup_function( void * vp)
|
||||
{
|
||||
thread_local_ptr< T > * p = static_cast< thread_local_ptr< T > * >( vp);
|
||||
BOOST_ASSERT( 0 != p);
|
||||
T * t = static_cast< T * >( ::pthread_getspecific( p->t_key_) );
|
||||
delete t;
|
||||
::pthread_setspecific( p->t_key_, 0);
|
||||
}
|
||||
|
||||
pthread_key_t this_key_;
|
||||
pthread_key_t t_key_;
|
||||
|
||||
public:
|
||||
thread_local_ptr() BOOST_NOEXCEPT :
|
||||
this_key_(), t_key_()
|
||||
{
|
||||
::pthread_key_create( & this_key_, & thread_local_ptr::cleanup_function);
|
||||
::pthread_key_create( & t_key_, 0);
|
||||
}
|
||||
|
||||
~thread_local_ptr()
|
||||
{ if ( 0 != t_) cleanup_function( t_); } // required for single-threaded apps
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL();
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{ return static_cast< T * >( ::pthread_getspecific( t_key_) ); }
|
||||
|
||||
bool operator!() const BOOST_NOEXCEPT
|
||||
{ return ! get(); }
|
||||
|
||||
bool operator==( thread_local_ptr const& other) BOOST_NOEXCEPT
|
||||
{ return this->get() == other.get(); }
|
||||
|
||||
bool operator!=( thread_local_ptr const& other) BOOST_NOEXCEPT
|
||||
{ return ! ( * this == other); }
|
||||
|
||||
void reset( T * t) BOOST_NOEXCEPT
|
||||
{
|
||||
::pthread_setspecific( this_key_, this);
|
||||
::pthread_setspecific( t_key_, t);
|
||||
}
|
||||
};
|
||||
# endif
|
||||
struct thread_local_ptr : public boost::thread_specific_ptr< T >
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user