Add SharedData::ConstAccess

This commit is contained in:
Vinnie Falco
2013-09-27 11:27:33 -07:00
parent 7e4c834c0e
commit 3acb474795
2 changed files with 52 additions and 79 deletions

View File

@@ -48,13 +48,20 @@ class CriticalSection;
ConstAccess acquires a shared lock on the mutex associated with the ConstAccess acquires a shared lock on the mutex associated with the
container. container.
- UnlockedAccess - ConstUnlockedAccess
Provides access to the shared state via a const reference or pointer. Provides access to the shared state via a const reference or pointer.
No locking is performed. It is the callers responsibility to ensure that No locking is performed. It is the callers responsibility to ensure that
the operation is synchronized. This can be useful for diagnostics or the operation is synchronized. This can be useful for diagnostics or
assertions, or for when it is known that no other threads can access assertions, or for when it is known that no other threads can access
the data. the data.
- UnlockedAccess
Provides access to the shared state via a reference or pointer.
No locking is performed. It is the callers responsibility to ensure that
the operation is synchronized. This can be useful for diagnostics or
assertions, or for when it is known that no other threads can access
the data.
Usage example: Usage example:
@code @code
@@ -115,6 +122,7 @@ public:
class Access; class Access;
class ConstAccess; class ConstAccess;
class UnlockedAccess; class UnlockedAccess;
class ConstUnlockedAccess;
/** Create a shared data container. /** Create a shared data container.
Up to 8 parameters can be specified in the constructor. These parameters Up to 8 parameters can be specified in the constructor. These parameters
@@ -174,44 +182,14 @@ public:
explicit Access (SharedData& state) explicit Access (SharedData& state)
: m_state (state) : m_state (state)
, m_lock (m_state.m_mutex) , m_lock (m_state.m_mutex)
{ { }
}
/** Returns a const reference to the data. */ Data const& get () const { return m_state.m_value; }
Data const& get () const Data const& operator* () const { return get (); }
{ Data const* operator-> () const { return &get (); }
return m_state.m_value; Data& get () { return m_state.m_value; }
} Data& operator* () { return get (); }
Data* operator-> () { return &get (); }
/** Returns a const reference to the data. */
Data const& operator* () const
{
return get ();
}
/** Returns a const pointer to the data. */
Data const* operator-> () const
{
return &get ();
}
/** Returns a non-const reference to the data. */
Data& get ()
{
return m_state.m_value;
}
/** Returns a non-const reference to the data. */
Data& operator* ()
{
return get ();
}
/** Returns a non-const pointer to the data. */
Data* operator-> ()
{
return &get ();
}
private: private:
SharedData& m_state; SharedData& m_state;
@@ -231,26 +209,11 @@ public:
explicit ConstAccess (SharedData const volatile& state) explicit ConstAccess (SharedData const volatile& state)
: m_state (const_cast <SharedData const&> (state)) : m_state (const_cast <SharedData const&> (state))
, m_lock (m_state.m_mutex) , m_lock (m_state.m_mutex)
{ { }
}
/** Returns a const reference to the data. */ Data const& get () const { return m_state.m_value; }
Data const& get () const Data const& operator* () const { return get (); }
{ Data const* operator-> () const { return &get (); }
return m_state.m_value;
}
/** Returns a const reference to the data. */
Data const& operator* () const
{
return get ();
}
/** Returns a const pointer to the data. */
Data const* operator-> () const
{
return &get ();
}
private: private:
SharedData const& m_state; SharedData const& m_state;
@@ -263,37 +226,47 @@ private:
This acquires a shared lock on the underlying mutex. This acquires a shared lock on the underlying mutex.
*/ */
template <class Data, class SharedMutexType> template <class Data, class SharedMutexType>
class SharedData <Data, SharedMutexType>::UnlockedAccess : public Uncopyable class SharedData <Data, SharedMutexType>::ConstUnlockedAccess : public Uncopyable
{ {
public: public:
/** Create an UnlockedAccess from the specified SharedData */ /** Create an UnlockedAccess from the specified SharedData */
explicit UnlockedAccess (SharedData const volatile& state) explicit ConstUnlockedAccess (SharedData const volatile& state)
: m_state (const_cast <SharedData const&> (state)) : m_state (const_cast <SharedData const&> (state))
{ { }
}
/** Returns a const reference to the data. */ Data const& get () const { return m_state.m_value; }
Data const& get () const Data const& operator* () const { return get (); }
{ Data const* operator-> () const { return &get (); }
return m_state.m_value;
}
/** Returns a const reference to the data. */
Data const& operator* () const
{
return get ();
}
/** Returns a const pointer to the data. */
Data const* operator-> () const
{
return &get ();
}
private: private:
SharedData const& m_state; SharedData const& m_state;
}; };
//------------------------------------------------------------------------------
/** Provides access to the contents of a SharedData.
This acquires a shared lock on the underlying mutex.
*/
template <class Data, class SharedMutexType>
class SharedData <Data, SharedMutexType>::UnlockedAccess : public Uncopyable
{
public:
/** Create an UnlockedAccess from the specified SharedData */
explicit UnlockedAccess (SharedData& state)
: m_state (state)
{ }
Data const& get () const { return m_state.m_value; }
Data const& operator* () const { return get (); }
Data const* operator-> () const { return &get (); }
Data& get () { return m_state.m_value; }
Data& operator* () { return get (); }
Data* operator-> () { return &get (); }
private:
SharedData& m_state;
};
} }
#endif #endif

View File

@@ -395,7 +395,7 @@ void TrackedMutex::acquired (char const* fileName, int lineNumber) const noexcep
else else
{ {
// Thread already had ownership of the mutex. // Thread already had ownership of the mutex.
bassert (SharedState::UnlockedAccess (m_state)->thread == &thread); bassert (SharedState::ConstUnlockedAccess (m_state)->thread == &thread);
// If this goes off it means we counted wrong. // If this goes off it means we counted wrong.
bassert (thread.refCount >= m_count); bassert (thread.refCount >= m_count);