Loki/include/loki/LockingPtr.h
rich_sposato d2ca522cca Added text of MIT License.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1115 7ec92016-0320-0410-acc4-a06ded1c099a
2011-09-23 00:46:21 +00:00

124 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code is from the article:
// "Generic<Programming>: volatile — Multithreaded Programmers Best Friend
// Volatile-Correctness or How to Have Your Compiler Detect Race Conditions
// for You" by Alexandrescu, Andrei.
// Published in the February 2001 issue of the C/C++ Users Journal.
// http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
//
// Code covered by the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Prepared for Loki library by Richard Sposato
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_LOCKING_PTR_INC_
#define LOKI_LOCKING_PTR_INC_
// $Id$
#include <loki/ConstPolicy.h>
#include <loki/Threads.h>
namespace Loki
{
/** @class LockingPtr
Locks a volatile object and casts away volatility so that the object
can be safely used in a single-threaded region of code.
Original version of LockingPtr had only one template - for the shared
object, but not the mutex type. This version allows users to specify a
the mutex type as a LockingPolicy class. The only requirements for a
LockingPolicy class are to provide Lock and Unlock methods.
*/
template < typename SharedObject, typename LockingPolicy = LOKI_DEFAULT_MUTEX,
template<class> class ConstPolicy = LOKI_DEFAULT_CONSTNESS >
class LockingPtr
{
public:
typedef typename ConstPolicy<SharedObject>::Type ConstOrNotType;
/** Constructor locks mutex associated with an object.
@param object Reference to object.
@param mutex Mutex used to control thread access to object.
*/
LockingPtr( volatile ConstOrNotType & object, LockingPolicy & mutex )
: pObject_( const_cast< SharedObject * >( &object ) ),
pMutex_( &mutex )
{
mutex.Lock();
}
typedef typename std::pair<volatile ConstOrNotType *, LockingPolicy *> Pair;
/** Constructor locks mutex associated with an object.
@param lockpair a std::pair of pointers to the object and the mutex
*/
explicit LockingPtr( Pair lockpair )
: pObject_( const_cast< SharedObject * >( lockpair.first ) ),
pMutex_( lockpair.second )
{
lockpair.second->Lock();
}
/// Destructor unlocks the mutex.
~LockingPtr()
{
pMutex_->Unlock();
}
/// Star-operator dereferences pointer.
ConstOrNotType & operator * ()
{
return *pObject_;
}
/// Point-operator returns pointer to object.
ConstOrNotType * operator -> ()
{
return pObject_;
}
private:
/// Default constructor is not implemented.
LockingPtr();
/// Copy-constructor is not implemented.
LockingPtr( const LockingPtr & );
/// Copy-assignment-operator is not implemented.
LockingPtr & operator = ( const LockingPtr & );
/// Pointer to the shared object.
ConstOrNotType * pObject_;
/// Pointer to the mutex.
LockingPolicy * pMutex_;
}; // end class LockingPtr
} // namespace Loki
#endif // end file guardian