mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
Add some thread classes and fix SharedData with a simple mutex adapter
This commit is contained in:
@@ -85,11 +85,17 @@
|
|||||||
<ClInclude Include="..\..\beast\Net.h" />
|
<ClInclude Include="..\..\beast\Net.h" />
|
||||||
<ClInclude Include="..\..\beast\net\IPEndpoint.h" />
|
<ClInclude Include="..\..\beast\net\IPEndpoint.h" />
|
||||||
<ClInclude Include="..\..\beast\StaticAssert.h" />
|
<ClInclude Include="..\..\beast\StaticAssert.h" />
|
||||||
|
<ClInclude Include="..\..\beast\Thread.h" />
|
||||||
|
<ClInclude Include="..\..\beast\thread\LockGuard.h" />
|
||||||
|
<ClInclude Include="..\..\beast\thread\SharedData.h" />
|
||||||
|
<ClInclude Include="..\..\beast\thread\SharedLockGuard.h" />
|
||||||
|
<ClInclude Include="..\..\beast\thread\SharedMutexAdapter.h" />
|
||||||
<ClInclude Include="..\..\beast\TypeTraits.h" />
|
<ClInclude Include="..\..\beast\TypeTraits.h" />
|
||||||
<ClInclude Include="..\..\beast\type_traits\IntegralConstant.h" />
|
<ClInclude Include="..\..\beast\type_traits\IntegralConstant.h" />
|
||||||
<ClInclude Include="..\..\beast\type_traits\IsIntegral.h" />
|
<ClInclude Include="..\..\beast\type_traits\IsIntegral.h" />
|
||||||
<ClInclude Include="..\..\beast\type_traits\IsSigned.h" />
|
<ClInclude Include="..\..\beast\type_traits\IsSigned.h" />
|
||||||
<ClInclude Include="..\..\beast\type_traits\RemoveSigned.h" />
|
<ClInclude Include="..\..\beast\type_traits\RemoveSigned.h" />
|
||||||
|
<ClInclude Include="..\..\beast\Uncopyable.h" />
|
||||||
<ClInclude Include="..\..\beast\Utility.h" />
|
<ClInclude Include="..\..\beast\Utility.h" />
|
||||||
<ClInclude Include="..\..\beast\utility\EnableIf.h" />
|
<ClInclude Include="..\..\beast\utility\EnableIf.h" />
|
||||||
<ClInclude Include="..\..\beast\utility\Journal.h" />
|
<ClInclude Include="..\..\beast\utility\Journal.h" />
|
||||||
@@ -224,7 +230,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\memory\SharedObject.h" />
|
<ClInclude Include="..\..\modules\beast_core\memory\SharedObject.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\ScopedPointer.h" />
|
<ClInclude Include="..\..\modules\beast_core\memory\ScopedPointer.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
|
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\Uncopyable.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\WeakReference.h" />
|
<ClInclude Include="..\..\modules\beast_core\memory\WeakReference.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\SharedPtr.h" />
|
<ClInclude Include="..\..\modules\beast_core\memory\SharedPtr.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\StaticObject.h" />
|
<ClInclude Include="..\..\modules\beast_core\memory\StaticObject.h" />
|
||||||
@@ -286,7 +291,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedLock.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\ScopedLock.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedReadLock.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\ScopedReadLock.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedWriteLock.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\ScopedWriteLock.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\SharedData.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\SpinLock.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\SpinLock.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\Thread.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\Thread.h" />
|
||||||
|
|||||||
@@ -204,6 +204,9 @@
|
|||||||
<Filter Include="beast\utility\impl">
|
<Filter Include="beast\utility\impl">
|
||||||
<UniqueIdentifier>{775ab0d6-aa5f-43d7-ab3b-3c01652a9ef1}</UniqueIdentifier>
|
<UniqueIdentifier>{775ab0d6-aa5f-43d7-ab3b-3c01652a9ef1}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="beast\thread">
|
||||||
|
<UniqueIdentifier>{da8084c0-491b-4eb0-b750-97182a9deed4}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||||
@@ -576,9 +579,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\Throw.h">
|
<ClInclude Include="..\..\modules\beast_core\diagnostic\Throw.h">
|
||||||
<Filter>beast_core\diagnostic</Filter>
|
<Filter>beast_core\diagnostic</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\Uncopyable.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\Interval.h">
|
<ClInclude Include="..\..\modules\beast_core\maths\Interval.h">
|
||||||
<Filter>beast_core\maths</Filter>
|
<Filter>beast_core\maths</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -699,9 +699,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\threads\ReadWriteMutex.h">
|
<ClInclude Include="..\..\modules\beast_core\threads\ReadWriteMutex.h">
|
||||||
<Filter>beast_core\threads</Filter>
|
<Filter>beast_core\threads</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\SharedData.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\thread\MutexTraits.h">
|
<ClInclude Include="..\..\modules\beast_core\thread\MutexTraits.h">
|
||||||
<Filter>beast_core\thread</Filter>
|
<Filter>beast_core\thread</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1080,6 +1077,24 @@
|
|||||||
<ClInclude Include="..\..\beast\mpl\IsCallPossible.h">
|
<ClInclude Include="..\..\beast\mpl\IsCallPossible.h">
|
||||||
<Filter>beast\mpl</Filter>
|
<Filter>beast\mpl</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\Thread.h">
|
||||||
|
<Filter>beast</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\thread\LockGuard.h">
|
||||||
|
<Filter>beast\thread</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\thread\SharedLockGuard.h">
|
||||||
|
<Filter>beast\thread</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\thread\SharedData.h">
|
||||||
|
<Filter>beast\thread</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\thread\SharedMutexAdapter.h">
|
||||||
|
<Filter>beast\thread</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\Uncopyable.h">
|
||||||
|
<Filter>beast</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
|
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
|
||||||
|
|||||||
28
beast/Thread.h
Normal file
28
beast/Thread.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_THREAD_H_INCLUDED
|
||||||
|
#define BEAST_THREAD_H_INCLUDED
|
||||||
|
|
||||||
|
#include "thread/LockGuard.h"
|
||||||
|
#include "thread/SharedLockGuard.h"
|
||||||
|
#include "thread/SharedMutexAdapter.h"
|
||||||
|
#include "thread/SharedData.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,6 +20,11 @@
|
|||||||
#ifndef BEAST_UNCOPYABLE_H_INCLUDED
|
#ifndef BEAST_UNCOPYABLE_H_INCLUDED
|
||||||
#define BEAST_UNCOPYABLE_H_INCLUDED
|
#define BEAST_UNCOPYABLE_H_INCLUDED
|
||||||
|
|
||||||
|
namespace beast
|
||||||
|
{
|
||||||
|
|
||||||
|
// Ideas from boost
|
||||||
|
|
||||||
/** Prevent copy construction and assignment.
|
/** Prevent copy construction and assignment.
|
||||||
|
|
||||||
This is used to suppress warnings and prevent unsafe operations on
|
This is used to suppress warnings and prevent unsafe operations on
|
||||||
@@ -59,12 +64,14 @@
|
|||||||
class Uncopyable
|
class Uncopyable
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
inline Uncopyable () { }
|
Uncopyable () { }
|
||||||
inline ~Uncopyable () { }
|
~Uncopyable () { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Uncopyable (Uncopyable const&);
|
Uncopyable (Uncopyable const&);
|
||||||
Uncopyable const& operator= (Uncopyable const&);
|
Uncopyable const& operator= (Uncopyable const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
51
beast/thread/LockGuard.h
Normal file
51
beast/thread/LockGuard.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_THREAD_LOCKGUARD_H_INCLUDED
|
||||||
|
#define BEAST_THREAD_LOCKGUARD_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../Uncopyable.h"
|
||||||
|
|
||||||
|
namespace beast
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename Mutex>
|
||||||
|
class LockGuard : public Uncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Mutex MutexType;
|
||||||
|
|
||||||
|
explicit LockGuard (Mutex const& mutex)
|
||||||
|
: m_mutex (mutex)
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~LockGuard ()
|
||||||
|
{
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex const& m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
299
beast/thread/SharedData.h
Normal file
299
beast/thread/SharedData.h
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_THREAD_SHAREDDATA_H_INCLUDED
|
||||||
|
#define BEAST_THREAD_SHAREDDATA_H_INCLUDED
|
||||||
|
|
||||||
|
namespace beast
|
||||||
|
{
|
||||||
|
|
||||||
|
class CriticalSection;
|
||||||
|
|
||||||
|
/** Structured, multi-threaded access to a shared state.
|
||||||
|
|
||||||
|
This container combines locking semantics with data access semantics to
|
||||||
|
create an alternative to the typical synchronization method of first
|
||||||
|
acquiring a lock and then accessing data members.
|
||||||
|
|
||||||
|
With this container, access to the underlying data is only possible after
|
||||||
|
first acquiring a lock. The steps of acquiring the lock and obtaining
|
||||||
|
a const or non-const reference to the data are combined into one
|
||||||
|
RAII style operation.
|
||||||
|
|
||||||
|
There are three types of access:
|
||||||
|
|
||||||
|
- Access
|
||||||
|
Provides access to the shared state via a non-const reference or pointer.
|
||||||
|
Access acquires a unique lock on the mutex associated with the
|
||||||
|
container.
|
||||||
|
|
||||||
|
- ConstAccess
|
||||||
|
Provides access to the shared state via a const reference or pointer.
|
||||||
|
ConstAccess acquires a shared lock on the mutex associated with the
|
||||||
|
container.
|
||||||
|
|
||||||
|
- UnlockedAccess
|
||||||
|
Provides access to the shared state via a const 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:
|
||||||
|
|
||||||
|
@code
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
int value1;
|
||||||
|
String value2;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SharedData <State> SharedState;
|
||||||
|
|
||||||
|
SharedState m_state;
|
||||||
|
|
||||||
|
void readExample ()
|
||||||
|
{
|
||||||
|
SharedState::ConstAccess state (m_state);
|
||||||
|
|
||||||
|
print (state->value1); // read access
|
||||||
|
print (state->value2); // read access
|
||||||
|
|
||||||
|
state->value1 = 42; // write disallowed: compile error
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeExample ()
|
||||||
|
{
|
||||||
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
|
state->value2 = "Label"; // write access, allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Requirements for Value:
|
||||||
|
Constructible
|
||||||
|
Destructible
|
||||||
|
|
||||||
|
Requirements for SharedMutexType:
|
||||||
|
X is SharedMutexType, a is an instance of X:
|
||||||
|
X a; DefaultConstructible
|
||||||
|
X::LockGuardType Names a type that implements the LockGuard concept.
|
||||||
|
X::SharedLockGuardType Names a type that implements the SharedLockGuard concept.
|
||||||
|
|
||||||
|
@tparam Value The type which the container holds.
|
||||||
|
@tparam SharedMutexType The type of shared mutex to use.
|
||||||
|
*/
|
||||||
|
template <typename Value, class SharedMutexType =
|
||||||
|
SharedMutexAdapter <CriticalSection> >
|
||||||
|
class SharedData : public Uncopyable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef typename SharedMutexType::LockGuardType LockGuardType;
|
||||||
|
typedef typename SharedMutexType::SharedLockGuardType SharedLockGuardType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Value ValueType;
|
||||||
|
|
||||||
|
class Access;
|
||||||
|
class ConstAccess;
|
||||||
|
class UnlockedAccess;
|
||||||
|
|
||||||
|
/** Create a shared data container.
|
||||||
|
Up to 8 parameters can be specified in the constructor. These parameters
|
||||||
|
are forwarded to the corresponding constructor in Data. If no
|
||||||
|
constructor in Data matches the parameter list, a compile error is
|
||||||
|
generated.
|
||||||
|
*/
|
||||||
|
/** @{ */
|
||||||
|
SharedData () { }
|
||||||
|
|
||||||
|
template <class T1>
|
||||||
|
explicit SharedData (T1 t1)
|
||||||
|
: m_value (t1) { }
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
SharedData (T1 t1, T2 t2)
|
||||||
|
: m_value (t1, t2) { }
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3>
|
||||||
|
SharedData (T1 t1, T2 t2, T3 t3)
|
||||||
|
: m_value (t1, t2, t3) { }
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3, class T4>
|
||||||
|
SharedData (T1 t1, T2 t2, T3 t3, T4 t4)
|
||||||
|
: m_value (t1, t2, t3, t4) { }
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3, class T4, class T5>
|
||||||
|
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
||||||
|
: m_value (t1, t2, t3, t4, t5) { }
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
||||||
|
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
||||||
|
: m_value (t1, t2, t3, t4, t5, t6) { }
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
||||||
|
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : m_value (t1, t2, t3, t4, t5, t6, t7) { }
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
||||||
|
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
||||||
|
: m_value (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
private:
|
||||||
|
Value m_value;
|
||||||
|
SharedMutexType m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Provides non-const access to the contents of a SharedData.
|
||||||
|
This acquires a unique lock on the underlying mutex.
|
||||||
|
*/
|
||||||
|
template <class Data, class SharedMutexType>
|
||||||
|
class SharedData <Data, SharedMutexType>::Access : public Uncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Access (SharedData& state)
|
||||||
|
: m_state (state)
|
||||||
|
, m_lock (m_state.m_mutex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a const reference to the data. */
|
||||||
|
Data const& get () const
|
||||||
|
{
|
||||||
|
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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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:
|
||||||
|
SharedData& m_state;
|
||||||
|
typename SharedData::LockGuardType m_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Provides const 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>::ConstAccess : public Uncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Create a ConstAccess from the specified SharedData */
|
||||||
|
explicit ConstAccess (SharedData const volatile& state)
|
||||||
|
: m_state (const_cast <SharedData const&> (state))
|
||||||
|
, m_lock (m_state.m_mutex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a const reference to the data. */
|
||||||
|
Data const& get () const
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
SharedData const& m_state;
|
||||||
|
typename SharedData::SharedLockGuardType m_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Provides const 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 const volatile& state)
|
||||||
|
: m_state (const_cast <SharedData const&> (state))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a const reference to the data. */
|
||||||
|
Data const& get () const
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
SharedData const& m_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
52
beast/thread/SharedLockGuard.h
Normal file
52
beast/thread/SharedLockGuard.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_THREAD_SHAREDLOCKGUARD_H_INCLUDED
|
||||||
|
#define BEAST_THREAD_SHAREDLOCKGUARD_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../Uncopyable.h"
|
||||||
|
|
||||||
|
namespace beast
|
||||||
|
{
|
||||||
|
|
||||||
|
/** A scoped container that acquires a shared lock. */
|
||||||
|
template <typename Mutex>
|
||||||
|
class SharedLockGuard : public Uncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Mutex MutexType;
|
||||||
|
|
||||||
|
explicit SharedLockGuard (Mutex const& mutex)
|
||||||
|
: m_mutex (mutex)
|
||||||
|
{
|
||||||
|
m_mutex.lock_shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
~SharedLockGuard ()
|
||||||
|
{
|
||||||
|
m_mutex.unlock_shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex const& m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
65
beast/thread/SharedMutexAdapter.h
Normal file
65
beast/thread/SharedMutexAdapter.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_THREAD_SHAREDMUTEXADAPTER_H_INCLUDED
|
||||||
|
#define BEAST_THREAD_SHAREDMUTEXADAPTER_H_INCLUDED
|
||||||
|
|
||||||
|
namespace beast
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Adapts a regular Lockable to conform to the SharedMutex concept.
|
||||||
|
Shared locks become unique locks with this interface. Two threads may not
|
||||||
|
simultaneously acquire ownership of the lock. Typically the Mutex template
|
||||||
|
parameter will be a CriticalSection.
|
||||||
|
*/
|
||||||
|
template <class Mutex>
|
||||||
|
class SharedMutexAdapter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Mutex MutexType;
|
||||||
|
typedef LockGuard <SharedMutexAdapter> LockGuardType;
|
||||||
|
typedef SharedLockGuard <SharedMutexAdapter> SharedLockGuardType;
|
||||||
|
|
||||||
|
void lock() const
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock() const
|
||||||
|
{
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock_shared() const
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock_shared() const
|
||||||
|
{
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex mutable m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -78,6 +78,7 @@
|
|||||||
|
|
||||||
#include "../../beast/CStdInt.h"
|
#include "../../beast/CStdInt.h"
|
||||||
#include "../../beast/StaticAssert.h"
|
#include "../../beast/StaticAssert.h"
|
||||||
|
#include "../../beast/Uncopyable.h"
|
||||||
|
|
||||||
namespace beast
|
namespace beast
|
||||||
{
|
{
|
||||||
@@ -94,7 +95,6 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
|
|||||||
// Add new includes to the bottom.
|
// Add new includes to the bottom.
|
||||||
|
|
||||||
#include "diagnostic/ContractChecks.h"
|
#include "diagnostic/ContractChecks.h"
|
||||||
#include "memory/Uncopyable.h"
|
|
||||||
#include "memory/Memory.h"
|
#include "memory/Memory.h"
|
||||||
#include "maths/MathsFunctions.h"
|
#include "maths/MathsFunctions.h"
|
||||||
#include "memory/ByteOrder.h"
|
#include "memory/ByteOrder.h"
|
||||||
@@ -108,6 +108,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
|
|||||||
// New header-only library modeled more closely according to boost
|
// New header-only library modeled more closely according to boost
|
||||||
#include "../../beast/intrusive/ForwardList.h"
|
#include "../../beast/intrusive/ForwardList.h"
|
||||||
#include "../../beast/Net.h"
|
#include "../../beast/Net.h"
|
||||||
|
#include "../../beast/Thread.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -161,7 +162,6 @@ namespace beast
|
|||||||
#include "memory/MemoryAlignment.h"
|
#include "memory/MemoryAlignment.h"
|
||||||
#include "memory/CacheLine.h"
|
#include "memory/CacheLine.h"
|
||||||
#include "threads/ReadWriteMutex.h"
|
#include "threads/ReadWriteMutex.h"
|
||||||
#include "threads/SharedData.h"
|
|
||||||
#include "diagnostic/SafeBool.h"
|
#include "diagnostic/SafeBool.h"
|
||||||
#include "threads/WaitableEvent.h"
|
#include "threads/WaitableEvent.h"
|
||||||
#include "threads/Thread.h"
|
#include "threads/Thread.h"
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
|
|
||||||
R operator() ()
|
R operator() ()
|
||||||
{
|
{
|
||||||
return m_f ();
|
return (m_f)();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -136,7 +136,7 @@ public:
|
|||||||
|
|
||||||
R operator() (P1 p1)
|
R operator() (P1 p1)
|
||||||
{
|
{
|
||||||
return m_f (p1);
|
return (m_f)(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -262,6 +262,22 @@ private:
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// bind() helpers for pointer to member function
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
const T* get_pointer (SharedPtr<T> const& ptr)
|
||||||
|
{
|
||||||
|
return ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T* get_pointer (SharedPtr<T>& ptr)
|
||||||
|
{
|
||||||
|
return ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
/** SharedPtr comparisons. */
|
/** SharedPtr comparisons. */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ public:
|
|||||||
|
|
||||||
void stateChanged ()
|
void stateChanged ()
|
||||||
{
|
{
|
||||||
SharedData <SharedState>::ReadAccess state (sharedState);
|
SharedData <SharedState>::ConstAccess state (sharedState);
|
||||||
|
|
||||||
// (read state)
|
// (read state)
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ public:
|
|||||||
|
|
||||||
void changeState ()
|
void changeState ()
|
||||||
{
|
{
|
||||||
SharedData <State>::WriteAccess state (sharedState);
|
SharedData <State>::Access state (sharedState);
|
||||||
|
|
||||||
// (read and write state)
|
// (read and write state)
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@
|
|||||||
void addListener (Listener* listener, CallQueue& callQueue)
|
void addListener (Listener* listener, CallQueue& callQueue)
|
||||||
{
|
{
|
||||||
// Acquire read access to the shared state.
|
// Acquire read access to the shared state.
|
||||||
SharedData <State>::ReadAccess state (m_state);
|
SharedData <State>::ConstAccess state (m_state);
|
||||||
|
|
||||||
// Add the listener.
|
// Add the listener.
|
||||||
m_listeners.add (listener, callQueue);
|
m_listeners.add (listener, callQueue);
|
||||||
@@ -171,7 +171,7 @@
|
|||||||
|
|
||||||
// Update shared state.
|
// Update shared state.
|
||||||
{
|
{
|
||||||
SharedData <State>::WriteAccess state (m_state);
|
SharedData <State>::Access state (m_state);
|
||||||
|
|
||||||
m_state->outputLevel = newOutputLevel;
|
m_state->outputLevel = newOutputLevel;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ bool TrackedMutex::Agent::getLockedList (Array <Record>& output)
|
|||||||
{
|
{
|
||||||
TrackedMutex const& mutex = *iter;
|
TrackedMutex const& mutex = *iter;
|
||||||
{
|
{
|
||||||
TrackedMutex::SharedState::ReadAccess state (mutex.m_state);
|
TrackedMutex::SharedState::ConstAccess state (mutex.m_state);
|
||||||
output.add (state->owner);
|
output.add (state->owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ String TrackedMutex::getName () const noexcept
|
|||||||
TrackedMutex::Record TrackedMutex::getOwnerRecord () const noexcept
|
TrackedMutex::Record TrackedMutex::getOwnerRecord () const noexcept
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
SharedState::ReadAccess state (m_state);
|
SharedState::ConstAccess state (m_state);
|
||||||
return state->owner;
|
return state->owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,7 +245,7 @@ TrackedMutex::Record TrackedMutex::getOwnerRecord () const noexcept
|
|||||||
TrackedMutex::Agent TrackedMutex::getOwnerAgent () const noexcept
|
TrackedMutex::Agent TrackedMutex::getOwnerAgent () const noexcept
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
SharedState::ReadAccess state (m_state);
|
SharedState::ConstAccess state (m_state);
|
||||||
if (state->thread != nullptr)
|
if (state->thread != nullptr)
|
||||||
return Agent (state->thread);
|
return Agent (state->thread);
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ void TrackedMutex::generateGlobalBlockedReport (StringArray& report)
|
|||||||
{
|
{
|
||||||
String s;
|
String s;
|
||||||
TrackedMutex const& mutex (*iter);
|
TrackedMutex const& mutex (*iter);
|
||||||
TrackedMutex::SharedState::ReadAccess state (mutex.m_state);
|
TrackedMutex::SharedState::ConstAccess state (mutex.m_state);
|
||||||
s << " " << mutex.getName () <<
|
s << " " << mutex.getName () <<
|
||||||
" from " << state->owner.getSourceLocation ();
|
" from " << state->owner.getSourceLocation ();
|
||||||
report.add (s);
|
report.add (s);
|
||||||
@@ -372,7 +372,7 @@ void TrackedMutex::acquired (char const* fileName, int lineNumber) const noexcep
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Take a state lock.
|
// Take a state lock.
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
// Set the mutex ownership record
|
// Set the mutex ownership record
|
||||||
state->owner = Record (getName (), threadName, sourceLocation);
|
state->owner = Record (getName (), threadName, sourceLocation);
|
||||||
@@ -428,7 +428,7 @@ void TrackedMutex::release () const noexcept
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Take the mutex' state lock
|
// Take the mutex' state lock
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
// Clear the mutex ownership record
|
// Clear the mutex ownership record
|
||||||
state->owner = Record ();
|
state->owner = Record ();
|
||||||
|
|||||||
@@ -1,295 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SHAREDDATA_H_INCLUDED
|
|
||||||
#define BEAST_SHAREDDATA_H_INCLUDED
|
|
||||||
|
|
||||||
/** Structured access to a shared state.
|
|
||||||
|
|
||||||
This template wraps an object containing members representing state
|
|
||||||
information shared between multiple threads of execution, where any thread
|
|
||||||
may need to read or write as needed. Synchronized access to the concurrent
|
|
||||||
state is enforced at compile time through strongly typed accessor classes.
|
|
||||||
This interface design facilitates source code pattern matching to find all
|
|
||||||
areas where a concurrent state is accessed.
|
|
||||||
|
|
||||||
There are three types of access:
|
|
||||||
|
|
||||||
- ReadAccess
|
|
||||||
|
|
||||||
Allows read access to the underlying object as `const`. ReadAccess may
|
|
||||||
be granted to one or more threads simultaneously. If one or more
|
|
||||||
threads have ReadAccess, requests to obtain WriteAccess are blocked.
|
|
||||||
|
|
||||||
- WriteAccess
|
|
||||||
|
|
||||||
Allows exclusive read/write access the underlying object. A WriteAccess
|
|
||||||
request blocks until all existing ReadAccess and WriteAccess requests
|
|
||||||
are released. While a WriteAccess exists, requests for ReadAccess
|
|
||||||
will block.
|
|
||||||
|
|
||||||
- UnlockedAccess
|
|
||||||
|
|
||||||
Allows read access to the underlying object without using the lock.
|
|
||||||
This can be helpful when designing concurrent structures through
|
|
||||||
composition. It also makes it easier to search for places in code
|
|
||||||
which use unlocked access.
|
|
||||||
|
|
||||||
This code example demonstrates various forms of access to a SharedData:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SharedData
|
|
||||||
{
|
|
||||||
int value1;
|
|
||||||
String value2;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef SharedData <SharedData> SharedState;
|
|
||||||
|
|
||||||
SharedState sharedState;
|
|
||||||
|
|
||||||
void readExample ()
|
|
||||||
{
|
|
||||||
SharedState::ReadAccess state (sharedState);
|
|
||||||
|
|
||||||
print (state->value1); // read access
|
|
||||||
print (state->value2); // read access
|
|
||||||
|
|
||||||
state->value1 = 42; // write disallowed: compile error
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeExample ()
|
|
||||||
{
|
|
||||||
SharedState::WriteAccess state (sharedState);
|
|
||||||
|
|
||||||
state->value2 = "Label"; // write access
|
|
||||||
}
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Forwarding constructors with up to eight parameters are provided. This lets
|
|
||||||
you write constructors into the underlying data object. For example:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SharedData
|
|
||||||
{
|
|
||||||
explicit SharedData (int numSlots)
|
|
||||||
{
|
|
||||||
m_array.reserve (numSlots);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector <AudioSampleBuffer*> m_array;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Construct SharedData with one parameter
|
|
||||||
SharedData <SharedData> sharedState (16);
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@param Object The type of object to encapsulate.
|
|
||||||
|
|
||||||
@warning Recursive calls are not supported. It is generally not possible for
|
|
||||||
a thread of execution to acquire write access while it already has
|
|
||||||
read access. Such an attempt will result in undefined behavior.
|
|
||||||
Calling into unknown code while holding a lock can cause deadlock.
|
|
||||||
See @ref CallQueue::queue().
|
|
||||||
*/
|
|
||||||
template <class Object>
|
|
||||||
class SharedData : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class ReadAccess;
|
|
||||||
class WriteAccess;
|
|
||||||
class UnlockedAccess;
|
|
||||||
|
|
||||||
/** Create a concurrent state.
|
|
||||||
|
|
||||||
Up to 8 parameters can be specified in the constructor. These parameters
|
|
||||||
are forwarded to the corresponding constructor in Object. If no
|
|
||||||
constructor in Object matches the parameter list, a compile error is
|
|
||||||
generated.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
SharedData () { }
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit SharedData (T1 t1)
|
|
||||||
: m_obj (t1) { }
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
SharedData (T1 t1, T2 t2)
|
|
||||||
: m_obj (t1, t2) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
SharedData (T1 t1, T2 t2, T3 t3)
|
|
||||||
: m_obj (t1, t2, t3) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
SharedData (T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
: m_obj (t1, t2, t3, t4) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
: m_obj (t1, t2, t3, t4, t5) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
: m_obj (t1, t2, t3, t4, t5, t6) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : m_obj (t1, t2, t3, t4, t5, t6, t7) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
: m_obj (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef ReadWriteMutex ReadWriteMutexType;
|
|
||||||
|
|
||||||
Object m_obj;
|
|
||||||
ReadWriteMutexType m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Unlocked access to a SharedData.
|
|
||||||
|
|
||||||
Use sparingly.
|
|
||||||
*/
|
|
||||||
template <class Object>
|
|
||||||
class SharedData <Object>::UnlockedAccess : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit UnlockedAccess (SharedData const& state)
|
|
||||||
: m_state (state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Object const& getObject () const
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
Object const& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
Object const* operator-> () const
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SharedData const& m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Read only access to a SharedData */
|
|
||||||
template <class Object>
|
|
||||||
class SharedData <Object>::ReadAccess : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create a ReadAccess from the specified SharedData */
|
|
||||||
explicit ReadAccess (SharedData const volatile& state)
|
|
||||||
: m_state (const_cast <SharedData const&> (state))
|
|
||||||
, m_lock (m_state.m_mutex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const& getObject () const
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only smart pointer to Object */
|
|
||||||
Object const* operator-> () const
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SharedData const& m_state;
|
|
||||||
ReadWriteMutexType::ScopedReadLockType m_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Read/write access to a SharedData */
|
|
||||||
template <class Object>
|
|
||||||
class SharedData <Object>::WriteAccess : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit WriteAccess (SharedData& state)
|
|
||||||
: m_state (state)
|
|
||||||
, m_lock (m_state.m_mutex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const* getObject () const
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only smart pointer to Object */
|
|
||||||
Object const* operator-> () const
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read/write pointer to Object */
|
|
||||||
Object& getObject ()
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read/write reference to Object */
|
|
||||||
Object& operator* ()
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read/write smart pointer to Object */
|
|
||||||
Object* operator-> ()
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SharedData& m_state;
|
|
||||||
ReadWriteMutexType::ScopedWriteLockType m_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#ifndef BEAST_THREAD_H_INCLUDED
|
#ifndef BEAST_JUCE_THREAD_H_INCLUDED
|
||||||
#define BEAST_THREAD_H_INCLUDED
|
#define BEAST_JUCE_THREAD_H_INCLUDED
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ public:
|
|||||||
, m_keyBlockDepth (keyBlockDepth)
|
, m_keyBlockDepth (keyBlockDepth)
|
||||||
, m_keyStorage (keyBytes)
|
, m_keyStorage (keyBytes)
|
||||||
{
|
{
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
openFile (&state->keyFile, keyPath);
|
openFile (&state->keyFile, keyPath);
|
||||||
|
|
||||||
@@ -289,7 +289,7 @@ public:
|
|||||||
|
|
||||||
~KeyvaDBImp ()
|
~KeyvaDBImp ()
|
||||||
{
|
{
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
flushInternal (state);
|
flushInternal (state);
|
||||||
}
|
}
|
||||||
@@ -310,7 +310,7 @@ public:
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
Result createMasterRecord (SharedState::WriteAccess& state)
|
Result createMasterRecord (SharedState::Access& state)
|
||||||
{
|
{
|
||||||
MemoryBlock buffer (masterHeaderBytes, true);
|
MemoryBlock buffer (masterHeaderBytes, true);
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ public:
|
|||||||
//
|
//
|
||||||
void readKeyRecord (KeyRecord* const keyRecord,
|
void readKeyRecord (KeyRecord* const keyRecord,
|
||||||
KeyIndex const keyIndex,
|
KeyIndex const keyIndex,
|
||||||
SharedState::WriteAccess& state)
|
SharedState::Access& state)
|
||||||
{
|
{
|
||||||
FileOffset const byteOffset = calcKeyRecordOffset (keyIndex);
|
FileOffset const byteOffset = calcKeyRecordOffset (keyIndex);
|
||||||
|
|
||||||
@@ -391,7 +391,7 @@ public:
|
|||||||
// Write a key record from memory
|
// Write a key record from memory
|
||||||
void writeKeyRecord (KeyRecord const& keyRecord,
|
void writeKeyRecord (KeyRecord const& keyRecord,
|
||||||
KeyIndex const keyIndex,
|
KeyIndex const keyIndex,
|
||||||
SharedState::WriteAccess& state,
|
SharedState::Access& state,
|
||||||
bool includingKey)
|
bool includingKey)
|
||||||
{
|
{
|
||||||
FileOffset const byteOffset = calcKeyRecordOffset (keyIndex);
|
FileOffset const byteOffset = calcKeyRecordOffset (keyIndex);
|
||||||
@@ -442,7 +442,7 @@ public:
|
|||||||
|
|
||||||
// Append a value to the value file.
|
// Append a value to the value file.
|
||||||
// VFALCO TODO return a Result
|
// VFALCO TODO return a Result
|
||||||
void writeValue (void const* const value, ByteSize valueBytes, SharedState::WriteAccess& state)
|
void writeValue (void const* const value, ByteSize valueBytes, SharedState::Access& state)
|
||||||
{
|
{
|
||||||
Result result = state->valFile.setPosition (state->valFileSize);
|
Result result = state->valFile.setPosition (state->valFileSize);
|
||||||
|
|
||||||
@@ -493,7 +493,7 @@ public:
|
|||||||
//
|
//
|
||||||
// Returns true if the key was found.
|
// Returns true if the key was found.
|
||||||
//
|
//
|
||||||
bool find (FindResult* findResult, void const* key, SharedState::WriteAccess& state)
|
bool find (FindResult* findResult, void const* key, SharedState::Access& state)
|
||||||
{
|
{
|
||||||
// Not okay to call this with an empty key file!
|
// Not okay to call this with an empty key file!
|
||||||
bassert (state->hasKeys ());
|
bassert (state->hasKeys ());
|
||||||
@@ -546,7 +546,7 @@ public:
|
|||||||
{
|
{
|
||||||
FindResult findResult (m_keyStorage.getData ());
|
FindResult findResult (m_keyStorage.getData ());
|
||||||
|
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
@@ -594,7 +594,7 @@ public:
|
|||||||
{
|
{
|
||||||
bassert (valueBytes > 0);
|
bassert (valueBytes > 0);
|
||||||
|
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
if (state->hasKeys ())
|
if (state->hasKeys ())
|
||||||
{
|
{
|
||||||
@@ -681,12 +681,12 @@ public:
|
|||||||
|
|
||||||
void flush ()
|
void flush ()
|
||||||
{
|
{
|
||||||
SharedState::WriteAccess state (m_state);
|
SharedState::Access state (m_state);
|
||||||
|
|
||||||
flushInternal (state);
|
flushInternal (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flushInternal (SharedState::WriteAccess& state)
|
void flushInternal (SharedState::Access& state)
|
||||||
{
|
{
|
||||||
state->keyFile.flush ();
|
state->keyFile.flush ();
|
||||||
state->valFile.flush ();
|
state->valFile.flush ();
|
||||||
|
|||||||
Reference in New Issue
Block a user