forked from boostorg/smart_ptr
This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17693]
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// typedef <implementation-defined> boost::detail::atomic_count;
|
||||
//
|
||||
// atomic_count a(n);
|
||||
//
|
||||
// (n is convertible to long)
|
||||
//
|
||||
// Effects: Constructs an atomic_count with an initial value of n
|
||||
//
|
||||
// a;
|
||||
//
|
||||
// Returns: (long) the current value of a
|
||||
//
|
||||
// ++a;
|
||||
//
|
||||
// Effects: Atomically increments the value of a
|
||||
// Returns: nothing
|
||||
//
|
||||
// --a;
|
||||
//
|
||||
// Effects: Atomically decrements the value of a
|
||||
// Returns: (long) zero if the new value of a is zero,
|
||||
// unspecified non-zero value otherwise (usually the new value)
|
||||
//
|
||||
// Important note: when --a returns zero, it must act as a
|
||||
// read memory barrier (RMB); i.e. the calling thread must
|
||||
// have a synchronized view of the memory
|
||||
//
|
||||
// On Intel IA-32 (x86) memory is always synchronized, so this
|
||||
// is not a problem.
|
||||
//
|
||||
// On many architectures the atomic instructions already act as
|
||||
// a memory barrier.
|
||||
//
|
||||
// This property is necessary for proper reference counting, since
|
||||
// a thread can update the contents of a shared object, then
|
||||
// release its reference, and another thread may immediately
|
||||
// release the last reference causing object destruction.
|
||||
//
|
||||
// The destructor needs to have a synchronized view of the
|
||||
// object to perform proper cleanup.
|
||||
//
|
||||
// Original example by Alexander Terekhov:
|
||||
//
|
||||
// Given:
|
||||
//
|
||||
// - a mutable shared object OBJ;
|
||||
// - two threads THREAD1 and THREAD2 each holding
|
||||
// a private smart_ptr object pointing to that OBJ.
|
||||
//
|
||||
// t1: THREAD1 updates OBJ (thread-safe via some synchronization)
|
||||
// and a few cycles later (after "unlock") destroys smart_ptr;
|
||||
//
|
||||
// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization
|
||||
// with respect to shared mutable object OBJ; OBJ destructors
|
||||
// are called driven by smart_ptr interface...
|
||||
//
|
||||
|
||||
// Note: atomic_count_linux.hpp has been disabled by default; see the
|
||||
// comments inside for more info.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifndef BOOST_HAS_THREADS
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef long atomic_count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#elif defined(BOOST_USE_ASM_ATOMIC_H)
|
||||
# include <boost/detail/atomic_count_linux.hpp>
|
||||
#elif defined(BOOST_AC_USE_PTHREADS)
|
||||
# include <boost/detail/atomic_count_pthreads.hpp>
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
# include <boost/detail/atomic_count_win32.hpp>
|
||||
#elif defined(__GLIBCPP__)
|
||||
# include <boost/detail/atomic_count_gcc.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# define BOOST_AC_USE_PTHREADS
|
||||
# include <boost/detail/atomic_count_pthreads.hpp>
|
||||
#else
|
||||
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
#error Unrecognized threading platform
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_gcc.hpp
|
||||
//
|
||||
// atomic_count for GNU libstdc++ v3
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <bits/atomicity.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v) : value_(v) {}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
__atomic_add(&value_, 1);
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return !__exchange_and_add(&value_, -1);
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return __exchange_and_add(&value_, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
_Atomic_word value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_linux.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
//
|
||||
// This implementation uses <asm/atomic.h>. This is a kernel header;
|
||||
// using kernel headers in a user program may cause a number of problems,
|
||||
// and not all flavors of Linux provide the atomic instructions.
|
||||
//
|
||||
// This file is only provided because the performance of this implementation
|
||||
// is significantly higher than the pthreads version. Use at your own risk
|
||||
// (by defining BOOST_USE_ASM_ATOMIC_H.)
|
||||
//
|
||||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v)
|
||||
{
|
||||
atomic_t init = ATOMIC_INIT(v);
|
||||
value_ = init;
|
||||
}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
atomic_inc(&value_);
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return !atomic_dec_and_test(&value_);
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return atomic_read(&value_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
atomic_t value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
|
||||
@@ -0,0 +1,97 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_pthreads.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
//
|
||||
// The generic pthread_mutex-based implementation sometimes leads to
|
||||
// inefficiencies. Example: a class with two atomic_count members
|
||||
// can get away with a single mutex.
|
||||
//
|
||||
// Users can detect this situation by checking BOOST_AC_USE_PTHREADS.
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
private:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
public:
|
||||
|
||||
scoped_lock(pthread_mutex_t & m): m_(m)
|
||||
{
|
||||
pthread_mutex_lock(&m_);
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
pthread_mutex_unlock(&m_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pthread_mutex_t & m_;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v): value_(v)
|
||||
{
|
||||
pthread_mutex_init(&mutex_, 0);
|
||||
}
|
||||
|
||||
~atomic_count()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
++value_;
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
return --value_;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
scoped_lock lock(mutex_);
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable pthread_mutex_t mutex_;
|
||||
long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||
@@ -0,0 +1,96 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_win32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
||||
|
||||
extern "C" long_type __cdecl _InterlockedIncrement(long volatile *);
|
||||
extern "C" long_type __cdecl _InterlockedDecrement(long volatile *);
|
||||
|
||||
#pragma intrinsic(_InterlockedIncrement)
|
||||
#pragma intrinsic(_InterlockedDecrement)
|
||||
|
||||
inline long InterlockedIncrement(long volatile * lp)
|
||||
{
|
||||
return _InterlockedIncrement(lp);
|
||||
}
|
||||
|
||||
inline long InterlockedDecrement(long volatile* lp)
|
||||
{
|
||||
return _InterlockedDecrement(lp);
|
||||
}
|
||||
|
||||
#else // _WIN64
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count(long v): value_(v)
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
// Some older <windows.h> versions do not accept volatile
|
||||
return InterlockedIncrement(const_cast<long*>(&value_));
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return InterlockedDecrement(const_cast<long*>(&value_));
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
volatile long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lightweight_mutex.hpp - lightweight mutex
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// typedef <unspecified> boost::detail::lightweight_mutex;
|
||||
//
|
||||
// boost::detail::lightweight_mutex meets a subset of the Mutex concept
|
||||
// requirements: http://www.boost.org/libs/thread/doc/mutex_concept.html#Mutex
|
||||
//
|
||||
// * Used by the smart pointer library
|
||||
// * Performance oriented
|
||||
// * Header-only implementation
|
||||
// * Small memory footprint
|
||||
// * Not a general purpose mutex, use boost::mutex, CRITICAL_SECTION or
|
||||
// pthread_mutex instead.
|
||||
// * Never spin in a tight lock/do-something/unlock loop, since
|
||||
// lightweight_mutex does not guarantee fairness.
|
||||
// * Never keep a lightweight_mutex locked for long periods.
|
||||
//
|
||||
// The current implementation can use a pthread_mutex, a CRITICAL_SECTION,
|
||||
// or a platform-specific spinlock.
|
||||
//
|
||||
// You can force a particular implementation by defining BOOST_LWM_USE_PTHREADS,
|
||||
// BOOST_LWM_USE_CRITICAL_SECTION, or BOOST_LWM_USE_SPINLOCK.
|
||||
//
|
||||
// If neither macro has been defined, the default is to use a spinlock on Win32,
|
||||
// and a pthread_mutex otherwise.
|
||||
//
|
||||
// Note that a spinlock is not a general synchronization primitive. In particular,
|
||||
// it is not guaranteed to be a memory barrier, and it is possible to "livelock"
|
||||
// if a lower-priority thread has acquired the spinlock but a higher-priority
|
||||
// thread is spinning trying to acquire the same lock.
|
||||
//
|
||||
// For these reasons, spinlocks have been disabled by default except on Windows,
|
||||
// where a spinlock can be several orders of magnitude faster than a CRITICAL_SECTION.
|
||||
|
||||
|
||||
// Note: lwm_linux.hpp has been disabled by default; see the comments
|
||||
// inside for more info.
|
||||
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Note to implementors: if you write a platform-specific spinlock
|
||||
// for a platform that supports pthreads, be sure to test its performance
|
||||
// against the pthreads-based version using shared_ptr_timing_test.cpp and
|
||||
// shared_ptr_mt_test.cpp. Custom versions are usually not worth the trouble
|
||||
// _unless_ the performance gains are substantial.
|
||||
//
|
||||
// Be sure to compare against a "real" pthreads library;
|
||||
// shared_ptr_timing_test.cpp will compile succesfully with a stub do-nothing
|
||||
// pthreads library, since it doesn't create any threads.
|
||||
|
||||
#ifndef BOOST_HAS_THREADS
|
||||
# include <boost/detail/lwm_nop.hpp>
|
||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(BOOST_USE_ASM_ATOMIC_H)
|
||||
# include <boost/detail/lwm_linux.hpp>
|
||||
#elif defined(BOOST_LWM_USE_CRITICAL_SECTION)
|
||||
# include <boost/detail/lwm_win32_cs.hpp>
|
||||
#elif defined(BOOST_LWM_USE_PTHREADS)
|
||||
# include <boost/detail/lwm_pthreads.hpp>
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
# include <boost/detail/lwm_win32.hpp>
|
||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__sgi)
|
||||
# include <boost/detail/lwm_irix.hpp>
|
||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__GLIBCPP__)
|
||||
# include <boost/detail/lwm_gcc.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# define BOOST_LWM_USE_PTHREADS
|
||||
# include <boost/detail/lwm_pthreads.hpp>
|
||||
#else
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
# error Unrecognized threading platform
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||
@@ -0,0 +1,78 @@
|
||||
#ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/lwm_gcc.hpp
|
||||
//
|
||||
// lightweight_mutex for GNU libstdc++ v3
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <bits/atomicity.h>
|
||||
#include <sched.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
_Atomic_word a_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): a_(1)
|
||||
{
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
lightweight_mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
while( !__exchange_and_add(&m_.a_, -1) )
|
||||
{
|
||||
__atomic_add(&m_.a_, 1);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
__atomic_add(&m_.a_, 1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
|
||||
@@ -0,0 +1,78 @@
|
||||
#ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_irix.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2002 Dan Gohman
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <sgidefs.h>
|
||||
#include <mutex.h>
|
||||
#include <sched.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
__uint32_t l_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): l_(0)
|
||||
{
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
lightweight_mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
while( test_and_set32(&m_.l_, 1) )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
m_.l_ = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_linux.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
//
|
||||
// This implementation uses <asm/atomic.h>. This is a kernel header;
|
||||
// using kernel headers in a user program may cause a number of problems,
|
||||
// and not all flavors of Linux provide the atomic instructions.
|
||||
//
|
||||
// This file is only provided because the performance of this implementation
|
||||
// is about 3.5 times higher than the pthreads version. Use at your own risk
|
||||
// (by defining BOOST_USE_ASM_ATOMIC_H.)
|
||||
//
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <sched.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
atomic_t a_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
atomic_t a = ATOMIC_INIT(1);
|
||||
a_ = a;
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
lightweight_mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
while( !atomic_dec_and_test(&m_.a_) )
|
||||
{
|
||||
atomic_inc(&m_.a_);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
atomic_inc(&m_.a_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_nop.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
public:
|
||||
|
||||
typedef lightweight_mutex scoped_lock;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_pthreads.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
pthread_mutex_t m_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
|
||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
||||
|
||||
#if defined(__hpux) && defined(_DECTHREADS_)
|
||||
pthread_mutex_init(&m_, pthread_mutexattr_default);
|
||||
#else
|
||||
pthread_mutex_init(&m_, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
{
|
||||
pthread_mutex_destroy(&m_);
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
pthread_mutex_t & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
scoped_lock(lightweight_mutex & m): m_(m.m_)
|
||||
{
|
||||
pthread_mutex_lock(&m_);
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
pthread_mutex_unlock(&m_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_win32.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8027 // Functions containing while are not expanded inline
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
|
||||
|
||||
extern "C" long_type __cdecl _InterlockedExchange(long volatile *, long);
|
||||
|
||||
#pragma intrinsic(_InterlockedExchange)
|
||||
|
||||
inline long InterlockedExchange(long volatile* lp, long l)
|
||||
{
|
||||
return _InterlockedExchange(lp, l);
|
||||
}
|
||||
|
||||
#else // _WIN64
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
long l_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex(): l_(0)
|
||||
{
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
lightweight_mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
while( InterlockedExchange(&m_.l_, 1) )
|
||||
{
|
||||
// Note: changed to Sleep(1) from Sleep(0).
|
||||
// According to MSDN, Sleep(0) will never yield
|
||||
// to a lower-priority thread, whereas Sleep(1)
|
||||
// will. Performance seems not to be affected.
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
InterlockedExchange(&m_.l_, 0);
|
||||
|
||||
// Note: adding a yield here will make
|
||||
// the spinlock more fair and will increase the overall
|
||||
// performance of some applications substantially in
|
||||
// high contention situations, but will penalize the
|
||||
// low contention / single thread case up to 5x
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8027 // Functions containing while are not expanded inline
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
|
||||
@@ -0,0 +1,103 @@
|
||||
#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lwm_win32_cs.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
struct CRITICAL_SECTION
|
||||
{
|
||||
struct critical_section_debug * DebugInfo;
|
||||
long LockCount;
|
||||
long RecursionCount;
|
||||
void * OwningThread;
|
||||
void * LockSemaphore;
|
||||
#if defined(_WIN64)
|
||||
unsigned __int64 SpinCount;
|
||||
#else
|
||||
unsigned long SpinCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
CRITICAL_SECTION cs_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
||||
public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
InitializeCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
{
|
||||
DeleteCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
class scoped_lock;
|
||||
friend class scoped_lock;
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
lightweight_mutex & m_;
|
||||
|
||||
scoped_lock(scoped_lock const &);
|
||||
scoped_lock & operator=(scoped_lock const &);
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock(lightweight_mutex & m): m_(m)
|
||||
{
|
||||
EnterCriticalSection(&m_.cs_);
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
LeaveCriticalSection(&m_.cs_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||
@@ -0,0 +1,152 @@
|
||||
#ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/shared_array_nmt.hpp - shared_array.hpp without member templates
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
#include <new> // for std::bad_alloc
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class shared_array
|
||||
{
|
||||
private:
|
||||
|
||||
typedef detail::atomic_count count_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit shared_array(T * p = 0): px(p)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try // prevent leak if new throws
|
||||
{
|
||||
pn = new count_type(1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_array_delete(p);
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pn = new count_type(1);
|
||||
|
||||
if(pn == 0)
|
||||
{
|
||||
boost::checked_array_delete(p);
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
~shared_array()
|
||||
{
|
||||
if(--*pn == 0)
|
||||
{
|
||||
boost::checked_array_delete(px);
|
||||
delete pn;
|
||||
}
|
||||
}
|
||||
|
||||
shared_array(shared_array const & r) : px(r.px) // never throws
|
||||
{
|
||||
pn = r.pn;
|
||||
++*pn;
|
||||
}
|
||||
|
||||
shared_array & operator=(shared_array const & r)
|
||||
{
|
||||
shared_array(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset(T * p = 0)
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px);
|
||||
shared_array(p).swap(*this);
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
T & operator[](std::ptrdiff_t i) const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
BOOST_ASSERT(i >= 0);
|
||||
return px[i];
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return *pn;
|
||||
}
|
||||
|
||||
bool unique() const // never throws
|
||||
{
|
||||
return *pn == 1;
|
||||
}
|
||||
|
||||
void swap(shared_array<T> & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
std::swap(pn, other.pn);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px; // contained pointer
|
||||
count_type * pn; // ptr to reference counter
|
||||
|
||||
}; // shared_array
|
||||
|
||||
template<class T, class U> inline bool operator==(shared_array<T> const & a, shared_array<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(shared_array<T> const & a, shared_array<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b)
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
||||
@@ -0,0 +1,183 @@
|
||||
#ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
# include <memory> // for std::auto_ptr
|
||||
#endif
|
||||
|
||||
#include <algorithm> // for std::swap
|
||||
#include <functional> // for std::less
|
||||
#include <new> // for std::bad_alloc
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class shared_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
typedef detail::atomic_count count_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef T value_type;
|
||||
|
||||
explicit shared_ptr(T * p = 0): px(p)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try // prevent leak if new throws
|
||||
{
|
||||
pn = new count_type(1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::checked_delete(p);
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pn = new count_type(1);
|
||||
|
||||
if(pn == 0)
|
||||
{
|
||||
boost::checked_delete(p);
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
~shared_ptr()
|
||||
{
|
||||
if(--*pn == 0)
|
||||
{
|
||||
boost::checked_delete(px);
|
||||
delete pn;
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr(shared_ptr const & r): px(r.px) // never throws
|
||||
{
|
||||
pn = r.pn;
|
||||
++*pn;
|
||||
}
|
||||
|
||||
shared_ptr & operator=(shared_ptr const & r)
|
||||
{
|
||||
shared_ptr(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
explicit shared_ptr(std::auto_ptr<T> & r)
|
||||
{
|
||||
pn = new count_type(1); // may throw
|
||||
px = r.release(); // fix: moved here to stop leak if new throws
|
||||
}
|
||||
|
||||
shared_ptr & operator=(std::auto_ptr<T> & r)
|
||||
{
|
||||
shared_ptr(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void reset(T * p = 0)
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px);
|
||||
shared_ptr(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator*() const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator->() const // never throws
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return *pn;
|
||||
}
|
||||
|
||||
bool unique() const // never throws
|
||||
{
|
||||
return *pn == 1;
|
||||
}
|
||||
|
||||
void swap(shared_ptr<T> & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
std::swap(pn, other.pn);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * px; // contained pointer
|
||||
count_type * pn; // ptr to reference counter
|
||||
};
|
||||
|
||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||
|
||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_this.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||
//
|
||||
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class enable_shared_from_this
|
||||
{
|
||||
public:
|
||||
|
||||
shared_ptr<T> shared_from_this()
|
||||
{
|
||||
shared_ptr<T> p(_internal_weak_this);
|
||||
BOOST_ASSERT(p.get() == this);
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<T const> shared_from_this() const
|
||||
{
|
||||
shared_ptr<T const> p(_internal_weak_this);
|
||||
BOOST_ASSERT(p.get() == this);
|
||||
return p;
|
||||
}
|
||||
|
||||
typedef T _internal_element_type; // for bcc 5.5.1
|
||||
weak_ptr<_internal_element_type> _internal_weak_this;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright Peter Dimov and David Abrahams 2002. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided
|
||||
// this copyright notice appears in all copies of the source. This
|
||||
// software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
#ifndef GET_POINTER_DWA20021219_HPP
|
||||
# define GET_POINTER_DWA20021219_HPP
|
||||
|
||||
# include <memory>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// get_pointer(p) extracts a ->* capable pointer from p
|
||||
|
||||
template<class T> T * get_pointer(T * p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
// get_pointer(shared_ptr<T> const & p) has been moved to shared_ptr.hpp
|
||||
|
||||
template<class T> T * get_pointer(std::auto_ptr<T> const& p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // GET_POINTER_DWA20021219_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// smart_ptr.hpp
|
||||
//
|
||||
// For compatibility, this header includes the headers for the four "classic"
|
||||
// smart pointer class templates.
|
||||
//
|
||||
// Copyright (c) 1998-2002 boost.org
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
//
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
@@ -0,0 +1,193 @@
|
||||
#ifndef BOOST_WEAK_PTR_HPP_INCLUDED
|
||||
#define BOOST_WEAK_PTR_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// weak_ptr.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4284) // odd return type for operator->
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> class weak_ptr
|
||||
{
|
||||
private:
|
||||
|
||||
// Borland 5.5.1 specific workarounds
|
||||
typedef weak_ptr<T> this_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
weak_ptr(): px(0), pn() // never throws in 1.30+
|
||||
{
|
||||
}
|
||||
|
||||
// generated copy constructor, assignment, destructor are fine
|
||||
|
||||
|
||||
//
|
||||
// The "obvious" converting constructor implementation:
|
||||
//
|
||||
// template<class Y>
|
||||
// weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// has a serious problem.
|
||||
//
|
||||
// r.px may already have been invalidated. The px(r.px)
|
||||
// conversion may require access to *r.px (virtual inheritance).
|
||||
//
|
||||
// It is not possible to avoid spurious access violations since
|
||||
// in multithreaded programs r.px may be invalidated at any point.
|
||||
//
|
||||
|
||||
template<class Y>
|
||||
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
|
||||
{
|
||||
px = r.lock().get();
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
|
||||
|
||||
template<class Y>
|
||||
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
||||
{
|
||||
px = r.lock().get();
|
||||
pn = r.pn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
||||
{
|
||||
px = r.px;
|
||||
pn = r.pn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
shared_ptr<T> lock() const // never throws
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
// optimization: avoid throw overhead
|
||||
if(expired())
|
||||
{
|
||||
return shared_ptr<element_type>();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return shared_ptr<element_type>(*this);
|
||||
}
|
||||
catch(bad_weak_ptr const &)
|
||||
{
|
||||
// Q: how can we get here?
|
||||
// A: another thread may have invalidated r after the use_count test above.
|
||||
return shared_ptr<element_type>();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// optimization: avoid try/catch overhead when single threaded
|
||||
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
bool expired() const // never throws
|
||||
{
|
||||
return pn.use_count() == 0;
|
||||
}
|
||||
|
||||
void reset() // never throws in 1.30+
|
||||
{
|
||||
this_type().swap(*this);
|
||||
}
|
||||
|
||||
void swap(this_type & other) // never throws
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
}
|
||||
|
||||
void _internal_assign(T * px2, detail::shared_count const & pn2)
|
||||
{
|
||||
px = px2;
|
||||
pn = pn2;
|
||||
}
|
||||
|
||||
template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
|
||||
{
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
|
||||
// Tasteless as this may seem, making all members public allows member templates
|
||||
// to work in the absence of member template friends. (Matthew Langston)
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
|
||||
private:
|
||||
|
||||
template<class Y> friend class weak_ptr;
|
||||
template<class Y> friend class shared_ptr;
|
||||
|
||||
#endif
|
||||
|
||||
T * px; // contained pointer
|
||||
detail::weak_count pn; // reference counter
|
||||
|
||||
}; // weak_ptr
|
||||
|
||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
|
||||
{
|
||||
return a._internal_less(b);
|
||||
}
|
||||
|
||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// deprecated, provided for backward compatibility
|
||||
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
|
||||
{
|
||||
return r.lock();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED
|
||||
Reference in New Issue
Block a user