diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj b/src/beast/Builds/VisualStudio2012/beast.vcxproj
index e89b435e5..19fbebb49 100644
--- a/src/beast/Builds/VisualStudio2012/beast.vcxproj
+++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj
@@ -140,6 +140,8 @@
+
+
@@ -151,19 +153,21 @@
-
-
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -175,6 +179,8 @@
+
+
@@ -245,7 +251,6 @@
-
@@ -280,11 +285,8 @@
-
-
-
@@ -327,17 +329,12 @@
-
-
-
-
-
@@ -492,6 +489,7 @@
true
+
true
true
@@ -505,25 +503,43 @@
true
-
+
true
true
true
true
-
+
true
true
true
true
-
+
true
true
true
true
-
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
true
true
@@ -542,6 +558,18 @@
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
@@ -729,12 +757,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
@@ -745,12 +767,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
@@ -859,12 +875,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
@@ -1147,36 +1157,12 @@
true
true
-
- true
- true
- true
- true
-
true
true
true
true
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
true
true
@@ -1189,12 +1175,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
index ac32658af..5a0913d2e 100644
--- a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -234,9 +234,6 @@
{775ab0d6-aa5f-43d7-ab3b-3c01652a9ef1}
-
- {da8084c0-491b-4eb0-b750-97182a9deed4}
-
{56ef157f-ad92-4da7-8fbf-00723f769732}
@@ -291,8 +288,11 @@
{4e9c54da-1581-41d7-ac75-48140e4a13d4}
-
- {96d46096-0e7d-4ca8-9d81-72f6834f88f8}
+
+ {f864ff58-1055-4c56-805f-9f181c4f0aa1}
+
+
+ {386a8cd8-6be3-4cac-9bca-7a01fdb5327a}
@@ -497,15 +497,6 @@
beast_core\threads
-
- beast_core\threads
-
-
- beast_core\threads
-
-
- beast_core\threads
-
beast_core\time
@@ -587,9 +578,6 @@
beast_core\diagnostic
-
- beast_core\diagnostic
-
beast_core\diagnostic
@@ -704,9 +692,6 @@
beast_core\diagnostic
-
- beast_core\threads
-
beast_core\thread
@@ -800,12 +785,6 @@
beast\mpl
-
- beast_core\memory
-
-
- beast_core\memory
-
beast_asio\async
@@ -938,9 +917,6 @@
beast_core\diagnostic
-
- beast_core\memory
-
beast_crypto\math
@@ -995,21 +971,6 @@
beast\mpl
-
- beast
-
-
- beast\thread
-
-
- beast\thread
-
-
- beast\thread
-
-
- beast\thread
-
beast
@@ -1037,9 +998,6 @@
beast\mpl
-
- beast_core\thread
-
beast\http\impl\http-parser
@@ -1212,32 +1170,65 @@
beast_asio\http
-
- beast\thread
-
-
- beast\thread
-
-
- beast\thread
-
beast\chrono
beast\chrono
-
- beast\thread
+
+ beast\smart_ptr
-
- beast\thread
+
+ beast\smart_ptr
-
- beast\thread
+
+ beast
-
- beast\thread
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\threads
+
+
+ beast\utility
+
+
+ beast\utility
+
+
+ beast\threads
@@ -1406,15 +1397,6 @@
beast_core\threads
-
- beast_core\threads
-
-
- beast_core\threads
-
-
- beast_core\threads
-
beast_core\time
@@ -1484,9 +1466,6 @@
beast_core\diagnostic
-
- beast_core\diagnostic
-
beast_core\threads
@@ -1565,9 +1544,6 @@
beast_core\diagnostic
-
- beast_core\threads
-
beast_core\thread\impl
@@ -1673,12 +1649,6 @@
beast_core\diagnostic
-
- beast_core\memory
-
-
- beast_core\diagnostic
-
beast_crypto\math
@@ -1703,9 +1673,6 @@
beast_asio\http
-
- beast_core\thread
-
beast\http\impl\http-parser
@@ -1775,20 +1742,38 @@
beast_asio\http
-
- beast\thread\impl
-
-
- beast\thread
-
beast\chrono\impl
-
- beast\thread\impl
+
+ beast\smart_ptr
-
- beast\thread\impl
+
+ beast\threads\impl
+
+
+ beast\threads\impl
+
+
+ beast\threads\impl
+
+
+ beast\threads\impl
+
+
+ beast\threads
+
+
+ beast\threads\impl
+
+
+ beast\utility\impl
+
+
+ beast\utility\impl
+
+
+ beast\threads\impl
diff --git a/src/beast/TODO.txt b/src/beast/TODO.txt
index 7ba271bd1..965d1721e 100644
--- a/src/beast/TODO.txt
+++ b/src/beast/TODO.txt
@@ -2,13 +2,6 @@
BEAST TODO
--------------------------------------------------------------------------------
-- Remove ReadWriteMutex and replace it with a CriticalSection
- since the implementation is broken.
-
-- Rewrite SharedData to work with a CriticalSection
-
-- Use new file naming convention
-
- Use SemanticVersion for beast version numbers to replace BEAST_VERSION
- add support for a __PRETTY_FUNCTION__ equivalent for all environments
diff --git a/src/beast/beast/SmartPtr.h b/src/beast/beast/SmartPtr.h
index 1bdf1d918..13aab726a 100644
--- a/src/beast/beast/SmartPtr.h
+++ b/src/beast/beast/SmartPtr.h
@@ -23,6 +23,8 @@
#include "Config.h"
#include "smart_ptr/ContainerDeletePolicy.h"
+#include "smart_ptr/SharedObject.h"
+#include "smart_ptr/SharedPtr.h"
#include "smart_ptr/ScopedPointer.h"
#endif
diff --git a/src/beast/beast/Threads.h b/src/beast/beast/Threads.h
new file mode 100644
index 000000000..7336bc777
--- /dev/null
+++ b/src/beast/beast/Threads.h
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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_THREADS_H_INCLUDED
+#define BEAST_THREADS_H_INCLUDED
+
+#include "threads/LockGuard.h"
+#include "threads/UnlockGuard.h"
+#include "threads/TryLockGuard.h"
+#include "threads/SharedLockGuard.h"
+#include "threads/SharedMutexAdapter.h"
+#include "threads/SharedData.h"
+#include "threads/ServiceQueue.h"
+#include "threads/SpinLock.h"
+#include "threads/Stoppable.h"
+#include "threads/Thread.h"
+#include "threads/ThreadLocalValue.h"
+#include "threads/WaitableEvent.h"
+
+#endif
diff --git a/src/beast/beast/Utility.h b/src/beast/beast/Utility.h
index f27cc5947..403f78ee3 100644
--- a/src/beast/beast/Utility.h
+++ b/src/beast/beast/Utility.h
@@ -24,6 +24,8 @@
#include "utility/EnableIf.h"
#include "utility/Error.h"
#include "utility/Journal.h"
+#include "utility/LeakChecked.h"
+#include "utility/StaticObject.h"
#endif
diff --git a/src/beast/beast/chrono/CPUMeter.h b/src/beast/beast/chrono/CPUMeter.h
index fd728a54e..b78da25d7 100644
--- a/src/beast/beast/chrono/CPUMeter.h
+++ b/src/beast/beast/chrono/CPUMeter.h
@@ -22,7 +22,7 @@
#include "RelativeTime.h"
#include "ScopedTimeInterval.h"
-#include "../thread/SharedData.h"
+#include "../threads/SharedData.h"
#include "../Atomic.h"
namespace beast {
diff --git a/src/beast/beast/smart_ptr/ScopedPointer.h b/src/beast/beast/smart_ptr/ScopedPointer.h
index 51d214d65..5e16c6451 100644
--- a/src/beast/beast/smart_ptr/ScopedPointer.h
+++ b/src/beast/beast/smart_ptr/ScopedPointer.h
@@ -24,9 +24,11 @@
#ifndef BEAST_SMARTPTR_SCOPEDPOINTER_H_INCLUDED
#define BEAST_SMARTPTR_SCOPEDPOINTER_H_INCLUDED
-#include "ContainerDeletePolicy.h"
+#include "../Config.h"
#include "../Uncopyable.h"
#include "../StaticAssert.h"
+
+#include "ContainerDeletePolicy.h"
namespace beast {
@@ -73,13 +75,13 @@ class ScopedPointer : public Uncopyable
public:
//==============================================================================
/** Creates a ScopedPointer containing a null pointer. */
- inline ScopedPointer() noexcept
+ inline ScopedPointer()
: object (nullptr)
{
}
/** Creates a ScopedPointer that owns the specified object. */
- inline ScopedPointer (ObjectType* const objectToTakePossessionOf) noexcept
+ inline ScopedPointer (ObjectType* const objectToTakePossessionOf)
: object (objectToTakePossessionOf)
{
}
@@ -90,7 +92,7 @@ public:
the pointer from the other object to this one, and the other object is reset to
be a null pointer.
*/
- ScopedPointer (ScopedPointer& objectToTransferFrom) noexcept
+ ScopedPointer (ScopedPointer& objectToTransferFrom)
: object (objectToTransferFrom.object)
{
objectToTransferFrom.object = nullptr;
@@ -150,13 +152,13 @@ public:
}
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
- ScopedPointer (ScopedPointer&& other) noexcept
+ ScopedPointer (ScopedPointer&& other)
: object (other.object)
{
other.object = nullptr;
}
- ScopedPointer& operator= (ScopedPointer&& other) noexcept
+ ScopedPointer& operator= (ScopedPointer&& other)
{
object = other.object;
other.object = nullptr;
@@ -166,28 +168,28 @@ public:
//==============================================================================
/** Returns the object that this ScopedPointer refers to. */
- inline operator ObjectType*() const noexcept { return object; }
+ inline operator ObjectType*() const { return object; }
/** Returns the object that this ScopedPointer refers to. */
- inline ObjectType* get() const noexcept { return object; }
+ inline ObjectType* get() const { return object; }
/** Returns the object that this ScopedPointer refers to. */
- inline ObjectType& operator*() const noexcept { return *object; }
+ inline ObjectType& operator*() const { return *object; }
/** Lets you access methods and properties of the object that this ScopedPointer refers to. */
- inline ObjectType* operator->() const noexcept { return object; }
+ inline ObjectType* operator->() const { return object; }
//==============================================================================
/** Removes the current object from this ScopedPointer without deleting it.
This will return the current object, and set the ScopedPointer to a null pointer.
*/
- ObjectType* release() noexcept { ObjectType* const o = object; object = nullptr; return o; }
+ ObjectType* release() { ObjectType* const o = object; object = nullptr; return o; }
//==============================================================================
/** Swaps this object with that of another ScopedPointer.
The two objects simply exchange their pointers.
*/
- void swapWith (ScopedPointer & other) noexcept
+ void swapWith (ScopedPointer & other)
{
// Two ScopedPointers should never be able to refer to the same object - if
// this happens, you must have done something dodgy!
@@ -206,7 +208,7 @@ private:
ObjectType* object;
// (Required as an alternative to the overloaded & operator).
- const ScopedPointer* getAddress() const noexcept { return this; }
+ const ScopedPointer* getAddress() const { return this; }
#if ! BEAST_MSVC // (MSVC can't deal with multiple copy constructors)
/* The copy constructors are private to stop people accidentally copying a const ScopedPointer
@@ -233,7 +235,7 @@ private:
This can be handy for checking whether this is a null pointer.
*/
template
-bool operator== (const ScopedPointer& pointer1, ObjectType* const pointer2) noexcept
+bool operator== (const ScopedPointer& pointer1, ObjectType* const pointer2)
{
return static_cast (pointer1) == pointer2;
}
@@ -242,7 +244,7 @@ bool operator== (const ScopedPointer& pointer1, ObjectType* const po
This can be handy for checking whether this is a null pointer.
*/
template
-bool operator!= (const ScopedPointer& pointer1, ObjectType* const pointer2) noexcept
+bool operator!= (const ScopedPointer& pointer1, ObjectType* const pointer2)
{
return static_cast (pointer1) != pointer2;
}
diff --git a/src/beast/modules/beast_core/memory/SharedObject.h b/src/beast/beast/smart_ptr/SharedObject.h
similarity index 98%
rename from src/beast/modules/beast_core/memory/SharedObject.h
rename to src/beast/beast/smart_ptr/SharedObject.h
index 8efd00aeb..53de02c7a 100644
--- a/src/beast/modules/beast_core/memory/SharedObject.h
+++ b/src/beast/beast/smart_ptr/SharedObject.h
@@ -24,6 +24,12 @@
#ifndef BEAST_SHAREDOBJECT_H_INCLUDED
#define BEAST_SHAREDOBJECT_H_INCLUDED
+#include "../Config.h"
+#include "../Atomic.h"
+#include "../Uncopyable.h"
+
+namespace beast {
+
//==============================================================================
/**
Adds reference-counting to an object.
@@ -194,4 +200,6 @@ private:
int refCount;
};
+}
+
#endif
diff --git a/src/beast/modules/beast_core/memory/SharedPtr.h b/src/beast/beast/smart_ptr/SharedPtr.h
similarity index 98%
rename from src/beast/modules/beast_core/memory/SharedPtr.h
rename to src/beast/beast/smart_ptr/SharedPtr.h
index f69431c5a..f1ce3754c 100644
--- a/src/beast/modules/beast_core/memory/SharedPtr.h
+++ b/src/beast/beast/smart_ptr/SharedPtr.h
@@ -21,8 +21,13 @@
*/
//==============================================================================
-#ifndef BEAST_CORE_SHAREDPTR_H_INCLUDED
-#define BEAST_CORE_SHAREDPTR_H_INCLUDED
+#ifndef BEAST_SMARTPTR_SHAREDPTR_H_INCLUDED
+#define BEAST_SMARTPTR_SHAREDPTR_H_INCLUDED
+
+#include "../Config.h"
+#include "SharedObject.h"
+
+namespace beast {
// Visual Studio doesn't seem to do very well when it comes
// to templated constructors and assignments so we provide
@@ -317,4 +322,6 @@ bool operator!= (T const* lhs, SharedPtr const& rhs) noexcept
}
/** @} */
+}
+
#endif
diff --git a/src/beast/beast/Thread.h b/src/beast/beast/smart_ptr/SmartPtr.cpp
similarity index 72%
rename from src/beast/beast/Thread.h
rename to src/beast/beast/smart_ptr/SmartPtr.cpp
index 72e83d69f..02700c564 100644
--- a/src/beast/beast/Thread.h
+++ b/src/beast/beast/smart_ptr/SmartPtr.cpp
@@ -17,18 +17,9 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_H_INCLUDED
-#define BEAST_THREAD_H_INCLUDED
+#include "BeastConfig.h"
-#include "thread/LockGuard.h"
-#include "thread/UnlockGuard.h"
-#include "thread/TryLockGuard.h"
-#include "thread/SharedLockGuard.h"
-#include "thread/SharedMutexAdapter.h"
-#include "thread/SharedData.h"
-#include "thread/ServiceQueue.h"
-#include "thread/SpinLock.h"
-#include "thread/ThreadLocalValue.h"
-#include "thread/WaitableEvent.h"
-
-#endif
+#include "ContainerDeletePolicy.h"
+#include "ScopedPointer.h"
+#include "SharedObject.h"
+#include "SharedPtr.h"
diff --git a/src/beast/beast/thread/LockGuard.h b/src/beast/beast/threads/LockGuard.h
similarity index 94%
rename from src/beast/beast/thread/LockGuard.h
rename to src/beast/beast/threads/LockGuard.h
index 44463df53..a90895ae0 100644
--- a/src/beast/beast/thread/LockGuard.h
+++ b/src/beast/beast/threads/LockGuard.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_LOCKGUARD_H_INCLUDED
-#define BEAST_THREAD_LOCKGUARD_H_INCLUDED
+#ifndef BEAST_THREADS_LOCKGUARD_H_INCLUDED
+#define BEAST_THREADS_LOCKGUARD_H_INCLUDED
#include "../Uncopyable.h"
diff --git a/src/beast/beast/thread/RecursiveMutex.h b/src/beast/beast/threads/RecursiveMutex.h
similarity index 96%
rename from src/beast/beast/thread/RecursiveMutex.h
rename to src/beast/beast/threads/RecursiveMutex.h
index b1d45adcf..15a233058 100644
--- a/src/beast/beast/thread/RecursiveMutex.h
+++ b/src/beast/beast/threads/RecursiveMutex.h
@@ -21,8 +21,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_RECURSIVEMUTEX_H_INCLUDED
-#define BEAST_THREAD_RECURSIVEMUTEX_H_INCLUDED
+#ifndef BEAST_THREADS_RECURSIVEMUTEX_H_INCLUDED
+#define BEAST_THREADS_RECURSIVEMUTEX_H_INCLUDED
#include "../Config.h"
#include "LockGuard.h"
diff --git a/src/beast/beast/thread/ServiceQueue.h b/src/beast/beast/threads/ServiceQueue.h
similarity index 99%
rename from src/beast/beast/thread/ServiceQueue.h
rename to src/beast/beast/threads/ServiceQueue.h
index a9f337ec1..2199615e7 100644
--- a/src/beast/beast/thread/ServiceQueue.h
+++ b/src/beast/beast/threads/ServiceQueue.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_SERVICEQUEUE_H_INCLUDED
-#define BEAST_THREAD_SERVICEQUEUE_H_INCLUDED
+#ifndef BEAST_THREADS_SERVICEQUEUE_H_INCLUDED
+#define BEAST_THREADS_SERVICEQUEUE_H_INCLUDED
#include "../chrono/CPUMeter.h"
#include "../intrusive/List.h"
diff --git a/src/beast/beast/thread/SharedData.h b/src/beast/beast/threads/SharedData.h
similarity index 99%
rename from src/beast/beast/thread/SharedData.h
rename to src/beast/beast/threads/SharedData.h
index 542054079..62e1defe7 100644
--- a/src/beast/beast/thread/SharedData.h
+++ b/src/beast/beast/threads/SharedData.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_SHAREDDATA_H_INCLUDED
-#define BEAST_THREAD_SHAREDDATA_H_INCLUDED
+#ifndef BEAST_THREADS_SHAREDDATA_H_INCLUDED
+#define BEAST_THREADS_SHAREDDATA_H_INCLUDED
#include "RecursiveMutex.h"
#include "SharedMutexAdapter.h"
diff --git a/src/beast/beast/thread/SharedLockGuard.h b/src/beast/beast/threads/SharedLockGuard.h
similarity index 93%
rename from src/beast/beast/thread/SharedLockGuard.h
rename to src/beast/beast/threads/SharedLockGuard.h
index 07fd7ab09..82fdbd081 100644
--- a/src/beast/beast/thread/SharedLockGuard.h
+++ b/src/beast/beast/threads/SharedLockGuard.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_SHAREDLOCKGUARD_H_INCLUDED
-#define BEAST_THREAD_SHAREDLOCKGUARD_H_INCLUDED
+#ifndef BEAST_THREADS_SHAREDLOCKGUARD_H_INCLUDED
+#define BEAST_THREADS_SHAREDLOCKGUARD_H_INCLUDED
#include "../Uncopyable.h"
diff --git a/src/beast/beast/thread/SharedMutexAdapter.h b/src/beast/beast/threads/SharedMutexAdapter.h
similarity index 94%
rename from src/beast/beast/thread/SharedMutexAdapter.h
rename to src/beast/beast/threads/SharedMutexAdapter.h
index b6fea1890..cb28ea51a 100644
--- a/src/beast/beast/thread/SharedMutexAdapter.h
+++ b/src/beast/beast/threads/SharedMutexAdapter.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_SHAREDMUTEXADAPTER_H_INCLUDED
-#define BEAST_THREAD_SHAREDMUTEXADAPTER_H_INCLUDED
+#ifndef BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
+#define BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
#include "LockGuard.h"
#include "SharedLockGuard.h"
diff --git a/src/beast/beast/thread/SpinLock.h b/src/beast/beast/threads/SpinLock.h
similarity index 97%
rename from src/beast/beast/thread/SpinLock.h
rename to src/beast/beast/threads/SpinLock.h
index 37501659c..cbc6e0e95 100644
--- a/src/beast/beast/thread/SpinLock.h
+++ b/src/beast/beast/threads/SpinLock.h
@@ -21,8 +21,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_SPINLOCK_H_INCLUDED
-#define BEAST_THREAD_SPINLOCK_H_INCLUDED
+#ifndef BEAST_THREADS_SPINLOCK_H_INCLUDED
+#define BEAST_THREADS_SPINLOCK_H_INCLUDED
#include "../Atomic.h"
#include "LockGuard.h"
diff --git a/src/beast/modules/beast_core/thread/Stoppable.h b/src/beast/beast/threads/Stoppable.h
similarity index 98%
rename from src/beast/modules/beast_core/thread/Stoppable.h
rename to src/beast/beast/threads/Stoppable.h
index c556df5d4..637b078c0 100644
--- a/src/beast/modules/beast_core/thread/Stoppable.h
+++ b/src/beast/beast/threads/Stoppable.h
@@ -17,8 +17,16 @@
*/
//==============================================================================
-#ifndef BEAST_CORE_STOPPABLE_H_INCLUDED
-#define BEAST_CORE_STOPPABLE_H_INCLUDED
+#ifndef BEAST_THREADS_STOPPABLE_H_INCLUDED
+#define BEAST_THREADS_STOPPABLE_H_INCLUDED
+
+#include "../Atomic.h"
+#include "../intrusive/LockFreeStack.h"
+#include "../utility/Journal.h"
+
+#include "WaitableEvent.h"
+
+namespace beast {
class RootStoppable;
@@ -314,4 +322,6 @@ private:
};
/** @} */
+}
+
#endif
diff --git a/src/beast/modules/beast_core/threads/Thread.h b/src/beast/beast/threads/Thread.h
similarity index 97%
rename from src/beast/modules/beast_core/threads/Thread.h
rename to src/beast/beast/threads/Thread.h
index 8cf8cf151..1ea34f7c1 100644
--- a/src/beast/modules/beast_core/threads/Thread.h
+++ b/src/beast/beast/threads/Thread.h
@@ -21,8 +21,14 @@
*/
//==============================================================================
-#ifndef BEAST_JUCE_THREAD_H_INCLUDED
-#define BEAST_JUCE_THREAD_H_INCLUDED
+#ifndef BEAST_THREADS_THREAD_H_INCLUDED
+#define BEAST_THREADS_THREAD_H_INCLUDED
+
+#include "../utility/LeakChecked.h"
+#include "RecursiveMutex.h"
+#include "WaitableEvent.h"
+
+namespace beast {
//==============================================================================
/**
@@ -265,7 +271,7 @@ private:
const String threadName;
void* volatile threadHandle;
ThreadID threadId;
- CriticalSection startStopLock;
+ RecursiveMutex startStopLock;
WaitableEvent startSuspensionEvent, defaultEvent;
int threadPriority;
uint32 affinityMask;
@@ -282,4 +288,7 @@ private:
static bool setThreadPriority (void*, int);
};
-#endif // BEAST_THREAD_H_INCLUDED
+}
+
+#endif
+
diff --git a/src/beast/beast/thread/ThreadLocalValue.h b/src/beast/beast/threads/ThreadLocalValue.h
similarity index 97%
rename from src/beast/beast/thread/ThreadLocalValue.h
rename to src/beast/beast/threads/ThreadLocalValue.h
index 4b7e4908d..751062efe 100644
--- a/src/beast/beast/thread/ThreadLocalValue.h
+++ b/src/beast/beast/threads/ThreadLocalValue.h
@@ -21,10 +21,12 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_THREADLOCALVALUE_H_INCLUDED
-#define BEAST_THREAD_THREADLOCALVALUE_H_INCLUDED
+#ifndef BEAST_THREADS_THREADLOCALVALUE_H_INCLUDED
+#define BEAST_THREADS_THREADLOCALVALUE_H_INCLUDED
#include "../Config.h"
+#include "SpinLock.h"
+#include "Thread.h"
namespace beast {
diff --git a/src/beast/beast/thread/Thread.cpp b/src/beast/beast/threads/Threads.cpp
similarity index 93%
rename from src/beast/beast/thread/Thread.cpp
rename to src/beast/beast/threads/Threads.cpp
index 7bd7438ec..a941c1e84 100644
--- a/src/beast/beast/thread/Thread.cpp
+++ b/src/beast/beast/threads/Threads.cpp
@@ -19,6 +19,9 @@
#include "BeastConfig.h"
+#include "impl/Atomic.cpp"
#include "impl/RecursiveMutex.cpp"
#include "impl/ServiceQueue.cpp"
+#include "impl/Stoppable.cpp"
+#include "impl/Thread.cpp"
#include "impl/WaitableEvent.cpp"
diff --git a/src/beast/beast/thread/TryLockGuard.h b/src/beast/beast/threads/TryLockGuard.h
similarity index 94%
rename from src/beast/beast/thread/TryLockGuard.h
rename to src/beast/beast/threads/TryLockGuard.h
index 0f9d65c14..f61f8bb6e 100644
--- a/src/beast/beast/thread/TryLockGuard.h
+++ b/src/beast/beast/threads/TryLockGuard.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_TRYLOCKGUARD_H_INCLUDED
-#define BEAST_THREAD_TRYLOCKGUARD_H_INCLUDED
+#ifndef BEAST_THREADS_TRYLOCKGUARD_H_INCLUDED
+#define BEAST_THREADS_TRYLOCKGUARD_H_INCLUDED
#include "../Uncopyable.h"
diff --git a/src/beast/beast/thread/UnlockGuard.h b/src/beast/beast/threads/UnlockGuard.h
similarity index 94%
rename from src/beast/beast/thread/UnlockGuard.h
rename to src/beast/beast/threads/UnlockGuard.h
index c53b4d06a..ea412765f 100644
--- a/src/beast/beast/thread/UnlockGuard.h
+++ b/src/beast/beast/threads/UnlockGuard.h
@@ -17,8 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THREAD_UNLOCKGUARD_H_INCLUDED
-#define BEAST_THREAD_UNLOCKGUARD_H_INCLUDED
+#ifndef BEAST_THREADS_UNLOCKGUARD_H_INCLUDED
+#define BEAST_THREADS_UNLOCKGUARD_H_INCLUDED
#include "../Uncopyable.h"
diff --git a/src/beast/beast/thread/WaitableEvent.h b/src/beast/beast/threads/WaitableEvent.h
similarity index 98%
rename from src/beast/beast/thread/WaitableEvent.h
rename to src/beast/beast/threads/WaitableEvent.h
index e4f419104..1e8b2a2cb 100644
--- a/src/beast/beast/thread/WaitableEvent.h
+++ b/src/beast/beast/threads/WaitableEvent.h
@@ -21,8 +21,8 @@
*/
//==============================================================================
-#ifndef BEAST_WAITABLEEVENT_H_INCLUDED
-#define BEAST_WAITABLEEVENT_H_INCLUDED
+#ifndef BEAST_THREADS_WAITABLEEVENT_H_INCLUDED
+#define BEAST_THREADS_WAITABLEEVENT_H_INCLUDED
#include "../Config.h"
#include "../Uncopyable.h"
diff --git a/src/beast/beast/threads/impl/Atomic.cpp b/src/beast/beast/threads/impl/Atomic.cpp
new file mode 100644
index 000000000..5f1790fd4
--- /dev/null
+++ b/src/beast/beast/threads/impl/Atomic.cpp
@@ -0,0 +1,133 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Portions of this file are from JUCE.
+ Copyright (c) 2013 - Raw Material Software Ltd.
+ Please visit http://www.juce.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.
+*/
+//==============================================================================
+
+#include "../../../modules/beast_core/beast_core.h" // for UnitTest
+
+namespace beast {
+
+class AtomicTests : public UnitTest
+{
+public:
+ AtomicTests() : UnitTest ("Atomic", "beast") {}
+
+ template
+ void testFloat ()
+ {
+ Atomic a, b;
+ a = (Type) 21;
+ memoryBarrier();
+
+ /* These are some simple test cases to check the atomics - let me know
+ if any of these assertions fail on your system!
+ */
+ expect (a.get() == (Type) 21);
+ expect (a.compareAndSetValue ((Type) 100, (Type) 50) == (Type) 21);
+ expect (a.get() == (Type) 21);
+ expect (a.compareAndSetValue ((Type) 101, a.get()) == (Type) 21);
+ expect (a.get() == (Type) 101);
+ expect (! a.compareAndSetBool ((Type) 300, (Type) 200));
+ expect (a.get() == (Type) 101);
+ expect (a.compareAndSetBool ((Type) 200, a.get()));
+ expect (a.get() == (Type) 200);
+
+ expect (a.exchange ((Type) 300) == (Type) 200);
+ expect (a.get() == (Type) 300);
+
+ b = a;
+ expect (b.get() == a.get());
+ }
+
+ template
+ void testInteger ()
+ {
+ Atomic a, b;
+ a.set ((Type) 10);
+ expect (a.value == (Type) 10);
+ expect (a.get() == (Type) 10);
+ a += (Type) 15;
+ expect (a.get() == (Type) 25);
+ memoryBarrier();
+ a -= (Type) 5;
+ expect (a.get() == (Type) 20);
+ expect (++a == (Type) 21);
+ ++a;
+ expect (--a == (Type) 21);
+ expect (a.get() == (Type) 21);
+ memoryBarrier();
+
+ testFloat ();
+ }
+
+ void runTest()
+ {
+ beginTestCase ("Misc");
+
+ char a1[7];
+ expect (numElementsInArray(a1) == 7);
+ int a2[3];
+ expect (numElementsInArray(a2) == 3);
+
+ expect (ByteOrder::swap ((uint16) 0x1122) == 0x2211);
+ expect (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);
+ expect (ByteOrder::swap ((uint64) literal64bit (0x1122334455667788)) == literal64bit (0x8877665544332211));
+
+ beginTestCase ("int");
+ testInteger ();
+
+ beginTestCase ("unsigned int");
+ testInteger ();
+
+ beginTestCase ("int32");
+ testInteger ();
+
+ beginTestCase ("uint32");
+ testInteger ();
+
+ beginTestCase ("long");
+ testInteger ();
+
+ beginTestCase ("void*");
+ testInteger ();
+
+ beginTestCase ("int*");
+ testInteger ();
+
+ beginTestCase ("float");
+ testFloat ();
+
+ #if ! BEAST_64BIT_ATOMICS_UNAVAILABLE // 64-bit intrinsics aren't available on some old platforms
+ beginTestCase ("int64");
+ testInteger ();
+
+ beginTestCase ("uint64");
+ testInteger ();
+
+ beginTestCase ("double");
+ testFloat ();
+ #endif
+ }
+};
+
+static AtomicTests atomicTests;
+
+}
diff --git a/src/beast/beast/thread/impl/RecursiveMutex.cpp b/src/beast/beast/threads/impl/RecursiveMutex.cpp
similarity index 100%
rename from src/beast/beast/thread/impl/RecursiveMutex.cpp
rename to src/beast/beast/threads/impl/RecursiveMutex.cpp
diff --git a/src/beast/beast/thread/impl/ServiceQueue.cpp b/src/beast/beast/threads/impl/ServiceQueue.cpp
similarity index 100%
rename from src/beast/beast/thread/impl/ServiceQueue.cpp
rename to src/beast/beast/threads/impl/ServiceQueue.cpp
diff --git a/src/beast/modules/beast_core/thread/Stoppable.cpp b/src/beast/beast/threads/impl/Stoppable.cpp
similarity index 98%
rename from src/beast/modules/beast_core/thread/Stoppable.cpp
rename to src/beast/beast/threads/impl/Stoppable.cpp
index fc6f57cdf..75e01986a 100644
--- a/src/beast/modules/beast_core/thread/Stoppable.cpp
+++ b/src/beast/beast/threads/impl/Stoppable.cpp
@@ -17,6 +17,10 @@
*/
//==============================================================================
+#include "../Stoppable.h"
+
+namespace beast {
+
Stoppable::Stoppable (char const* name, RootStoppable& root)
: m_name (name)
, m_root (root)
@@ -190,3 +194,5 @@ void RootStoppable::stopAsync ()
stopAsyncRecursive ();
}
+
+}
diff --git a/src/beast/beast/threads/impl/Thread.cpp b/src/beast/beast/threads/impl/Thread.cpp
new file mode 100644
index 000000000..d6969552b
--- /dev/null
+++ b/src/beast/beast/threads/impl/Thread.cpp
@@ -0,0 +1,599 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Portions of this file are from JUCE.
+ Copyright (c) 2013 - Raw Material Software Ltd.
+ Please visit http://www.juce.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.
+*/
+//==============================================================================
+
+#include "../Thread.h"
+
+namespace beast {
+
+Thread::Thread (const String& threadName_)
+ : threadName (threadName_),
+ threadHandle (nullptr),
+ threadId (0),
+ threadPriority (5),
+ affinityMask (0),
+ shouldExit (false)
+{
+}
+
+Thread::~Thread()
+{
+ /* If your thread class's destructor has been called without first stopping the thread, that
+ means that this partially destructed object is still performing some work - and that's
+ probably a Bad Thing!
+
+ To avoid this type of nastiness, always make sure you call stopThread() before or during
+ your subclass's destructor.
+ */
+ check_precondition (! isThreadRunning());
+
+ stopThread ();
+}
+
+//==============================================================================
+// Use a ref-counted object to hold this shared data, so that it can outlive its static
+// shared pointer when threads are still running during static shutdown.
+struct CurrentThreadHolder : public SharedObject
+{
+ CurrentThreadHolder() noexcept {}
+
+ typedef SharedPtr Ptr;
+ ThreadLocalValue value;
+};
+
+static char currentThreadHolderLock [sizeof (SpinLock)]; // (statically initialised to zeros).
+
+static SpinLock* castToSpinLockWithoutAliasingWarning (void* s)
+{
+ return static_cast (s);
+}
+
+static CurrentThreadHolder::Ptr getCurrentThreadHolder()
+{
+ static CurrentThreadHolder::Ptr currentThreadHolder;
+ SpinLock::ScopedLockType lock (*castToSpinLockWithoutAliasingWarning (currentThreadHolderLock));
+
+ if (currentThreadHolder == nullptr)
+ currentThreadHolder = new CurrentThreadHolder();
+
+ return currentThreadHolder;
+}
+
+void Thread::threadEntryPoint()
+{
+ const CurrentThreadHolder::Ptr currentThreadHolder (getCurrentThreadHolder());
+ currentThreadHolder->value = this;
+
+ if (threadName.isNotEmpty())
+ setCurrentThreadName (threadName);
+
+ if (startSuspensionEvent.wait (10000))
+ {
+ bassert (getCurrentThreadId() == threadId);
+
+ if (affinityMask != 0)
+ setCurrentThreadAffinityMask (affinityMask);
+
+ run();
+ }
+
+ currentThreadHolder->value.releaseCurrentThreadStorage();
+ closeThreadHandle();
+}
+
+// used to wrap the incoming call from the platform-specific code
+void BEAST_API beast_threadEntryPoint (void* userData)
+{
+ static_cast (userData)->threadEntryPoint();
+}
+
+//==============================================================================
+void Thread::startThread()
+{
+ const RecursiveMutex::ScopedLockType sl (startStopLock);
+
+ shouldExit = false;
+
+ if (threadHandle == nullptr)
+ {
+ launchThread();
+ setThreadPriority (threadHandle, threadPriority);
+ startSuspensionEvent.signal();
+ }
+}
+
+void Thread::startThread (const int priority)
+{
+ const RecursiveMutex::ScopedLockType sl (startStopLock);
+
+ if (threadHandle == nullptr)
+ {
+ threadPriority = priority;
+ startThread();
+ }
+ else
+ {
+ setPriority (priority);
+ }
+}
+
+bool Thread::isThreadRunning() const
+{
+ return threadHandle != nullptr;
+}
+
+Thread* Thread::getCurrentThread()
+{
+ return getCurrentThreadHolder()->value.get();
+}
+
+//==============================================================================
+void Thread::signalThreadShouldExit()
+{
+ shouldExit = true;
+}
+
+bool Thread::waitForThreadToExit (const int timeOutMilliseconds) const
+{
+ // Doh! So how exactly do you expect this thread to wait for itself to stop??
+ bassert (getThreadId() != getCurrentThreadId() || getCurrentThreadId() == 0);
+
+ const uint32 timeoutEnd = Time::getMillisecondCounter() + (uint32) timeOutMilliseconds;
+
+ while (isThreadRunning())
+ {
+ if (timeOutMilliseconds >= 0 && Time::getMillisecondCounter() > timeoutEnd)
+ return false;
+
+ sleep (2);
+ }
+
+ return true;
+}
+
+bool Thread::stopThread (const int timeOutMilliseconds)
+{
+ bool cleanExit = true;
+
+ // agh! You can't stop the thread that's calling this method! How on earth
+ // would that work??
+ bassert (getCurrentThreadId() != getThreadId());
+
+ const RecursiveMutex::ScopedLockType sl (startStopLock);
+
+ if (isThreadRunning())
+ {
+ signalThreadShouldExit();
+ notify();
+
+ if (timeOutMilliseconds != 0)
+ {
+ cleanExit = waitForThreadToExit (timeOutMilliseconds);
+ }
+
+ if (isThreadRunning())
+ {
+ bassert (! cleanExit);
+
+ // very bad karma if this point is reached, as there are bound to be
+ // locks and events left in silly states when a thread is killed by force..
+ killThread();
+
+ threadHandle = nullptr;
+ threadId = 0;
+
+ cleanExit = false;
+ }
+ else
+ {
+ cleanExit = true;
+ }
+ }
+
+ return cleanExit;
+}
+
+void Thread::stopThreadAsync ()
+{
+ const RecursiveMutex::ScopedLockType sl (startStopLock);
+
+ if (isThreadRunning())
+ {
+ signalThreadShouldExit();
+ notify();
+ }
+}
+
+//==============================================================================
+bool Thread::setPriority (const int newPriority)
+{
+ // NB: deadlock possible if you try to set the thread prio from the thread itself,
+ // so using setCurrentThreadPriority instead in that case.
+ if (getCurrentThreadId() == getThreadId())
+ return setCurrentThreadPriority (newPriority);
+
+ const RecursiveMutex::ScopedLockType sl (startStopLock);
+
+ if (setThreadPriority (threadHandle, newPriority))
+ {
+ threadPriority = newPriority;
+ return true;
+ }
+
+ return false;
+}
+
+bool Thread::setCurrentThreadPriority (const int newPriority)
+{
+ return setThreadPriority (0, newPriority);
+}
+
+void Thread::setAffinityMask (const uint32 newAffinityMask)
+{
+ affinityMask = newAffinityMask;
+}
+
+//==============================================================================
+bool Thread::wait (const int timeOutMilliseconds) const
+{
+ return defaultEvent.wait (timeOutMilliseconds);
+}
+
+void Thread::notify() const
+{
+ defaultEvent.signal();
+}
+
+//==============================================================================
+
+// This is here so we dont have circular includes
+//
+void SpinLock::enter() const noexcept
+{
+ if (! tryEnter())
+ {
+ for (int i = 20; --i >= 0;)
+ if (tryEnter())
+ return;
+
+ while (! tryEnter())
+ Thread::yield();
+ }
+}
+
+}
+
+//------------------------------------------------------------------------------
+
+#if BEAST_WINDOWS
+
+#include
+#include
+#include
+
+namespace beast {
+
+HWND beast_messageWindowHandle = 0; // (this is used by other parts of the codebase)
+
+void BEAST_API beast_threadEntryPoint (void*);
+
+static unsigned int __stdcall threadEntryProc (void* userData)
+{
+ if (beast_messageWindowHandle != 0)
+ AttachThreadInput (GetWindowThreadProcessId (beast_messageWindowHandle, 0),
+ GetCurrentThreadId(), TRUE);
+
+ beast_threadEntryPoint (userData);
+
+ _endthreadex (0);
+ return 0;
+}
+
+void Thread::launchThread()
+{
+ unsigned int newThreadId;
+ threadHandle = (void*) _beginthreadex (0, 0, &threadEntryProc, this, 0, &newThreadId);
+ threadId = (ThreadID) newThreadId;
+}
+
+void Thread::closeThreadHandle()
+{
+ CloseHandle ((HANDLE) threadHandle);
+ threadId = 0;
+ threadHandle = 0;
+}
+
+void Thread::killThread()
+{
+ if (threadHandle != 0)
+ {
+ #if BEAST_DEBUG
+ OutputDebugStringA ("** Warning - Forced thread termination **\n");
+ #endif
+ TerminateThread (threadHandle, 0);
+ }
+}
+
+void Thread::setCurrentThreadName (const String& name)
+{
+ #if BEAST_DEBUG && BEAST_MSVC
+ struct
+ {
+ DWORD dwType;
+ LPCSTR szName;
+ DWORD dwThreadID;
+ DWORD dwFlags;
+ } info;
+
+ info.dwType = 0x1000;
+ info.szName = name.toUTF8();
+ info.dwThreadID = GetCurrentThreadId();
+ info.dwFlags = 0;
+
+ __try
+ {
+ RaiseException (0x406d1388 /*MS_VC_EXCEPTION*/, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
+ }
+ __except (EXCEPTION_CONTINUE_EXECUTION)
+ {}
+ #else
+ (void) name;
+ #endif
+}
+
+Thread::ThreadID Thread::getCurrentThreadId()
+{
+ return (ThreadID) (pointer_sized_int) GetCurrentThreadId();
+}
+
+bool Thread::setThreadPriority (void* handle, int priority)
+{
+ int pri = THREAD_PRIORITY_TIME_CRITICAL;
+
+ if (priority < 1) pri = THREAD_PRIORITY_IDLE;
+ else if (priority < 2) pri = THREAD_PRIORITY_LOWEST;
+ else if (priority < 5) pri = THREAD_PRIORITY_BELOW_NORMAL;
+ else if (priority < 7) pri = THREAD_PRIORITY_NORMAL;
+ else if (priority < 9) pri = THREAD_PRIORITY_ABOVE_NORMAL;
+ else if (priority < 10) pri = THREAD_PRIORITY_HIGHEST;
+
+ if (handle == 0)
+ handle = GetCurrentThread();
+
+ return SetThreadPriority (handle, pri) != FALSE;
+}
+
+void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
+{
+ SetThreadAffinityMask (GetCurrentThread(), affinityMask);
+}
+
+struct SleepEvent
+{
+ SleepEvent() noexcept
+ : handle (CreateEvent (nullptr, FALSE, FALSE,
+ #if BEAST_DEBUG
+ _T("BEAST Sleep Event")))
+ #else
+ nullptr))
+ #endif
+ {}
+
+ ~SleepEvent() noexcept
+ {
+ CloseHandle (handle);
+ handle = 0;
+ }
+
+ HANDLE handle;
+};
+
+static SleepEvent sleepEvent;
+
+void BEAST_CALLTYPE Thread::sleep (const int millisecs)
+{
+ if (millisecs >= 10 || sleepEvent.handle == 0)
+ {
+ Sleep ((DWORD) millisecs);
+ }
+ else
+ {
+ // unlike Sleep() this is guaranteed to return to the current thread after
+ // the time expires, so we'll use this for short waits, which are more likely
+ // to need to be accurate
+ WaitForSingleObject (sleepEvent.handle, (DWORD) millisecs);
+ }
+}
+
+void Thread::yield()
+{
+ Sleep (0);
+}
+
+}
+
+//------------------------------------------------------------------------------
+
+#else
+
+#include
+#if BEAST_BSD
+ // ???
+#else
+# include
+#endif
+
+namespace beast {
+
+void BEAST_CALLTYPE Thread::sleep (int millisecs)
+{
+ struct timespec time;
+ time.tv_sec = millisecs / 1000;
+ time.tv_nsec = (millisecs % 1000) * 1000000;
+ nanosleep (&time, nullptr);
+}
+
+void BEAST_API beast_threadEntryPoint (void*);
+
+extern "C" void* threadEntryProc (void*);
+extern "C" void* threadEntryProc (void* userData)
+{
+ BEAST_AUTORELEASEPOOL
+ {
+ #if BEAST_ANDROID
+ struct AndroidThreadScope
+ {
+ AndroidThreadScope() { threadLocalJNIEnvHolder.attach(); }
+ ~AndroidThreadScope() { threadLocalJNIEnvHolder.detach(); }
+ };
+
+ const AndroidThreadScope androidEnv;
+ #endif
+
+ beast_threadEntryPoint (userData);
+ }
+
+ return nullptr;
+}
+
+void Thread::launchThread()
+{
+ threadHandle = 0;
+ pthread_t handle = 0;
+
+ if (pthread_create (&handle, 0, threadEntryProc, this) == 0)
+ {
+ pthread_detach (handle);
+ threadHandle = (void*) handle;
+ threadId = (ThreadID) threadHandle;
+ }
+}
+
+void Thread::closeThreadHandle()
+{
+ threadId = 0;
+ threadHandle = 0;
+}
+
+void Thread::killThread()
+{
+ if (threadHandle != 0)
+ {
+ #if BEAST_ANDROID
+ bassertfalse; // pthread_cancel not available!
+ #else
+ pthread_cancel ((pthread_t) threadHandle);
+ #endif
+ }
+}
+
+void Thread::setCurrentThreadName (const String& name)
+{
+ #if BEAST_IOS || (BEAST_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
+ BEAST_AUTORELEASEPOOL
+ {
+ [[NSThread currentThread] setName: beastStringToNS (name)];
+ }
+ #elif BEAST_LINUX
+ #if (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012
+ pthread_setname_np (pthread_self(), name.toRawUTF8());
+ #else
+ prctl (PR_SET_NAME, name.toRawUTF8(), 0, 0, 0);
+ #endif
+ #endif
+}
+
+bool Thread::setThreadPriority (void* handle, int priority)
+{
+ struct sched_param param;
+ int policy;
+ priority = blimit (0, 10, priority);
+
+ if (handle == nullptr)
+ handle = (void*) pthread_self();
+
+ if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0)
+ return false;
+
+ policy = priority == 0 ? SCHED_OTHER : SCHED_RR;
+
+ const int minPriority = sched_get_priority_min (policy);
+ const int maxPriority = sched_get_priority_max (policy);
+
+ param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority;
+ return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0;
+}
+
+Thread::ThreadID Thread::getCurrentThreadId()
+{
+ return (ThreadID) pthread_self();
+}
+
+void Thread::yield()
+{
+ sched_yield();
+}
+
+//==============================================================================
+/* Remove this macro if you're having problems compiling the cpu affinity
+ calls (the API for these has changed about quite a bit in various Linux
+ versions, and a lot of distros seem to ship with obsolete versions)
+*/
+#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES)
+ #define SUPPORT_AFFINITIES 1
+#endif
+
+void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
+{
+ #if SUPPORT_AFFINITIES
+ cpu_set_t affinity;
+ CPU_ZERO (&affinity);
+
+ for (int i = 0; i < 32; ++i)
+ if ((affinityMask & (1 << i)) != 0)
+ CPU_SET (i, &affinity);
+
+ /*
+ N.B. If this line causes a compile error, then you've probably not got the latest
+ version of glibc installed.
+
+ If you don't want to update your copy of glibc and don't care about cpu affinities,
+ then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0.
+ */
+ sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity);
+ sched_yield();
+
+ #else
+ /* affinities aren't supported because either the appropriate header files weren't found,
+ or the SUPPORT_AFFINITIES macro was turned off
+ */
+ bassertfalse;
+ (void) affinityMask;
+ #endif
+}
+
+}
+
+//------------------------------------------------------------------------------
+
+#endif
+
diff --git a/src/beast/beast/thread/impl/WaitableEvent.cpp b/src/beast/beast/threads/impl/WaitableEvent.cpp
similarity index 100%
rename from src/beast/beast/thread/impl/WaitableEvent.cpp
rename to src/beast/beast/threads/impl/WaitableEvent.cpp
diff --git a/src/beast/modules/beast_core/diagnostic/LeakChecked.h b/src/beast/beast/utility/LeakChecked.h
similarity index 94%
rename from src/beast/modules/beast_core/diagnostic/LeakChecked.h
rename to src/beast/beast/utility/LeakChecked.h
index 6e63f9fe5..296d315ef 100644
--- a/src/beast/modules/beast_core/diagnostic/LeakChecked.h
+++ b/src/beast/beast/utility/LeakChecked.h
@@ -17,11 +17,17 @@
*/
//==============================================================================
-#ifndef BEAST_LEAKCHECKED_H_INCLUDED
-#define BEAST_LEAKCHECKED_H_INCLUDED
+#ifndef BEAST_UTILITY_LEAKCHECKED_H_INCLUDED
+#define BEAST_UTILITY_LEAKCHECKED_H_INCLUDED
-namespace detail
-{
+#include "../Config.h"
+#include "../Atomic.h"
+#include "../intrusive/LockFreeStack.h"
+#include "StaticObject.h"
+
+namespace beast {
+
+namespace detail {
class LeakCheckedBase
{
@@ -169,4 +175,6 @@ using detail::disabled::LeakChecked;
using detail::disabled::LeakCheckedBase;
#endif
+}
+
#endif
diff --git a/src/beast/modules/beast_core/memory/StaticObject.h b/src/beast/beast/utility/StaticObject.h
similarity index 96%
rename from src/beast/modules/beast_core/memory/StaticObject.h
rename to src/beast/beast/utility/StaticObject.h
index 8b0d5a93f..30ab11cb9 100644
--- a/src/beast/modules/beast_core/memory/StaticObject.h
+++ b/src/beast/beast/utility/StaticObject.h
@@ -17,8 +17,10 @@
*/
//==============================================================================
-#ifndef BEAST_STATICOBJECT_H_INCLUDED
-#define BEAST_STATICOBJECT_H_INCLUDED
+#ifndef BEAST_UTILITY_STATICOBJECT_H_INCLUDED
+#define BEAST_UTILITY_STATICOBJECT_H_INCLUDED
+
+namespace beast {
// Spec: N2914=09-0104
//
@@ -106,4 +108,6 @@ private:
};
};
+}
+
#endif
diff --git a/src/beast/beast/utility/Utility.cpp b/src/beast/beast/utility/Utility.cpp
index 0eac28256..f66ea5a69 100644
--- a/src/beast/beast/utility/Utility.cpp
+++ b/src/beast/beast/utility/Utility.cpp
@@ -21,8 +21,10 @@
#include "impl/Error.cpp"
-
// For Journal and Debug
#include "../../modules/beast_core/beast_core.h"
-#include "impl/Journal.cpp"
+
#include "impl/Debug.cpp"
+#include "impl/Journal.cpp"
+#include "impl/LeakChecked.cpp"
+#include "impl/StaticObject.cpp"
diff --git a/src/beast/modules/beast_core/diagnostic/LeakChecked.cpp b/src/beast/beast/utility/impl/LeakChecked.cpp
similarity index 98%
rename from src/beast/modules/beast_core/diagnostic/LeakChecked.cpp
rename to src/beast/beast/utility/impl/LeakChecked.cpp
index 7f7d51b64..2209995e6 100644
--- a/src/beast/modules/beast_core/diagnostic/LeakChecked.cpp
+++ b/src/beast/beast/utility/impl/LeakChecked.cpp
@@ -17,6 +17,10 @@
*/
//==============================================================================
+#include "../LeakChecked.h"
+
+namespace beast {
+
namespace detail
{
@@ -124,3 +128,5 @@ void LeakCheckedBase::checkForLeaks ()
}
}
+
+}
diff --git a/src/beast/modules/beast_core/memory/StaticObject.cpp b/src/beast/beast/utility/impl/StaticObject.cpp
similarity index 93%
rename from src/beast/modules/beast_core/memory/StaticObject.cpp
rename to src/beast/beast/utility/impl/StaticObject.cpp
index 7482b0a17..5b44bb0dd 100644
--- a/src/beast/modules/beast_core/memory/StaticObject.cpp
+++ b/src/beast/beast/utility/impl/StaticObject.cpp
@@ -17,6 +17,11 @@
*/
//==============================================================================
+#include "../StaticObject.h"
+#include "../../threads/Thread.h"
+
+namespace beast {
+
namespace detail
{
@@ -32,3 +37,5 @@ void staticObjectWait (std::size_t n)
}
}
+
+}
diff --git a/src/beast/modules/beast_core/beast_core.cpp b/src/beast/modules/beast_core/beast_core.cpp
index da04f4dbe..8608e180d 100644
--- a/src/beast/modules/beast_core/beast_core.cpp
+++ b/src/beast/modules/beast_core/beast_core.cpp
@@ -137,7 +137,6 @@ namespace beast
#include "diagnostic/FatalError.cpp"
#include "diagnostic/FPUFlags.cpp"
-#include "diagnostic/LeakChecked.cpp"
#include "diagnostic/SemanticVersion.cpp"
#include "diagnostic/UnitTest.cpp"
#include "diagnostic/UnitTestUtilities.cpp"
@@ -161,7 +160,6 @@ namespace beast
#include "maths/Random.cpp"
#include "memory/MemoryBlock.cpp"
-#include "memory/StaticObject.cpp"
#include "misc/Main.cpp"
#include "misc/Result.cpp"
@@ -192,17 +190,12 @@ namespace beast
#include "thread/impl/TrackedMutex.cpp"
#include "thread/DeadlineTimer.cpp"
-#include "thread/Stoppable.cpp"
#include "thread/Semaphore.cpp"
#include "thread/Workers.cpp"
#include "threads/ChildProcess.cpp"
#include "threads/ReadWriteLock.cpp"
-#include "threads/ReadWriteMutex.cpp"
#include "threads/SpinDelay.cpp"
-#include "threads/Thread.cpp"
-#include "threads/ThreadPool.cpp"
-#include "threads/TimeSliceThread.cpp"
#include "time/PerformanceCounter.cpp"
#include "time/AtExitHook.cpp"
diff --git a/src/beast/modules/beast_core/beast_core.h b/src/beast/modules/beast_core/beast_core.h
index aa34fde6c..fff039ba9 100644
--- a/src/beast/modules/beast_core/beast_core.h
+++ b/src/beast/modules/beast_core/beast_core.h
@@ -58,7 +58,7 @@
#include "../../beast/SafeBool.h"
#include "../../beast/Strings.h"
#include "../../beast/TypeTraits.h"
-#include "../../beast/Thread.h"
+#include "../../beast/Threads.h"
#include "../../beast/Utility.h"
#include "../../beast/Chrono.h"
@@ -81,10 +81,8 @@ class FileOutputStream;
#include "memory/AtomicPointer.h"
#include "memory/AtomicState.h"
#include "threads/SpinDelay.h"
-#include "memory/StaticObject.h"
#include "time/AtExitHook.h"
-#include "diagnostic/LeakChecked.h"
#include "time/Time.h"
#include "threads/ScopedLock.h"
#include "threads/CriticalSection.h"
@@ -147,8 +145,6 @@ class FileOutputStream;
#include "memory/MemoryAlignment.h"
#include "memory/CacheLine.h"
-#include "threads/ReadWriteMutex.h"
-#include "threads/Thread.h"
#include "thread/MutexTraits.h"
#include "thread/TrackedMutex.h"
#include "diagnostic/FatalError.h"
@@ -157,8 +153,6 @@ class FileOutputStream;
#include "maths/uint24.h"
#include "logging/Logger.h"
#include "diagnostic/FPUFlags.h"
-#include "memory/SharedObject.h"
-#include "memory/SharedPtr.h"
#include "memory/SharedFunction.h"
#include "containers/AbstractFifo.h"
#include "text/Identifier.h"
@@ -223,8 +217,6 @@ class FileOutputStream;
#include "threads/Process.h"
#include "threads/ScopedReadLock.h"
#include "threads/ScopedWriteLock.h"
-#include "threads/ThreadPool.h"
-#include "threads/TimeSliceThread.h"
#include "diagnostic/UnitTest.h"
#include "xml/XmlDocument.h"
#include "xml/XmlElement.h"
@@ -238,7 +230,6 @@ class FileOutputStream;
#include "thread/DeadlineTimer.h"
#include "thread/Semaphore.h"
-#include "thread/Stoppable.h"
#include "thread/Workers.h"
}
diff --git a/src/beast/modules/beast_core/diagnostic/UnitTest.h b/src/beast/modules/beast_core/diagnostic/UnitTest.h
index 7f1d67175..72b9140f8 100644
--- a/src/beast/modules/beast_core/diagnostic/UnitTest.h
+++ b/src/beast/modules/beast_core/diagnostic/UnitTest.h
@@ -170,8 +170,7 @@ public:
}
};
- /** The type of a list of tests.
- */
+ /** The type of a list of tests. */
typedef Array TestList;
//--------------------------------------------------------------------------
diff --git a/src/beast/modules/beast_core/native/posix_SharedCode.h b/src/beast/modules/beast_core/native/posix_SharedCode.h
index 95e72f9c3..4d72928d4 100644
--- a/src/beast/modules/beast_core/native/posix_SharedCode.h
+++ b/src/beast/modules/beast_core/native/posix_SharedCode.h
@@ -39,13 +39,6 @@ bool CriticalSection::tryEnter() const noexcept { return pthread_mutex_trylock (
void CriticalSection::exit() const noexcept { pthread_mutex_unlock (&mutex); }
//==============================================================================
-void BEAST_CALLTYPE Thread::sleep (int millisecs)
-{
- struct timespec time;
- time.tv_sec = millisecs / 1000;
- time.tv_nsec = (millisecs % 1000) * 1000000;
- nanosleep (&time, nullptr);
-}
void Process::terminate()
{
@@ -913,146 +906,7 @@ void InterProcessLock::exit()
}
//==============================================================================
-void BEAST_API beast_threadEntryPoint (void*);
-extern "C" void* threadEntryProc (void*);
-extern "C" void* threadEntryProc (void* userData)
-{
- BEAST_AUTORELEASEPOOL
- {
- #if BEAST_ANDROID
- struct AndroidThreadScope
- {
- AndroidThreadScope() { threadLocalJNIEnvHolder.attach(); }
- ~AndroidThreadScope() { threadLocalJNIEnvHolder.detach(); }
- };
-
- const AndroidThreadScope androidEnv;
- #endif
-
- beast_threadEntryPoint (userData);
- }
-
- return nullptr;
-}
-
-void Thread::launchThread()
-{
- threadHandle = 0;
- pthread_t handle = 0;
-
- if (pthread_create (&handle, 0, threadEntryProc, this) == 0)
- {
- pthread_detach (handle);
- threadHandle = (void*) handle;
- threadId = (ThreadID) threadHandle;
- }
-}
-
-void Thread::closeThreadHandle()
-{
- threadId = 0;
- threadHandle = 0;
-}
-
-void Thread::killThread()
-{
- if (threadHandle != 0)
- {
- #if BEAST_ANDROID
- bassertfalse; // pthread_cancel not available!
- #else
- pthread_cancel ((pthread_t) threadHandle);
- #endif
- }
-}
-
-void Thread::setCurrentThreadName (const String& name)
-{
- #if BEAST_IOS || (BEAST_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
- BEAST_AUTORELEASEPOOL
- {
- [[NSThread currentThread] setName: beastStringToNS (name)];
- }
- #elif BEAST_LINUX
- #if (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012
- pthread_setname_np (pthread_self(), name.toRawUTF8());
- #else
- prctl (PR_SET_NAME, name.toRawUTF8(), 0, 0, 0);
- #endif
- #endif
-}
-
-bool Thread::setThreadPriority (void* handle, int priority)
-{
- struct sched_param param;
- int policy;
- priority = blimit (0, 10, priority);
-
- if (handle == nullptr)
- handle = (void*) pthread_self();
-
- if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0)
- return false;
-
- policy = priority == 0 ? SCHED_OTHER : SCHED_RR;
-
- const int minPriority = sched_get_priority_min (policy);
- const int maxPriority = sched_get_priority_max (policy);
-
- param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority;
- return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0;
-}
-
-Thread::ThreadID Thread::getCurrentThreadId()
-{
- return (ThreadID) pthread_self();
-}
-
-void Thread::yield()
-{
- sched_yield();
-}
-
-//==============================================================================
-/* Remove this macro if you're having problems compiling the cpu affinity
- calls (the API for these has changed about quite a bit in various Linux
- versions, and a lot of distros seem to ship with obsolete versions)
-*/
-#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES)
- #define SUPPORT_AFFINITIES 1
-#endif
-
-void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
-{
- #if SUPPORT_AFFINITIES
- cpu_set_t affinity;
- CPU_ZERO (&affinity);
-
- for (int i = 0; i < 32; ++i)
- if ((affinityMask & (1 << i)) != 0)
- CPU_SET (i, &affinity);
-
- /*
- N.B. If this line causes a compile error, then you've probably not got the latest
- version of glibc installed.
-
- If you don't want to update your copy of glibc and don't care about cpu affinities,
- then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0.
- */
- sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity);
- sched_yield();
-
- #else
- /* affinities aren't supported because either the appropriate header files weren't found,
- or the SUPPORT_AFFINITIES macro was turned off
- */
- bassertfalse;
- (void) affinityMask;
- #endif
-}
-
-//==============================================================================
bool DynamicLibrary::open (const String& name)
{
close();
diff --git a/src/beast/modules/beast_core/native/win32_Threads.cpp b/src/beast/modules/beast_core/native/win32_Threads.cpp
index 6c7742787..019a6d900 100644
--- a/src/beast/modules/beast_core/native/win32_Threads.cpp
+++ b/src/beast/modules/beast_core/native/win32_Threads.cpp
@@ -21,8 +21,6 @@
*/
//==============================================================================
-HWND beast_messageWindowHandle = 0; // (this is used by other parts of the codebase)
-
void* getUser32Function (const char* functionName)
{
HMODULE module = GetModuleHandleA ("user32.dll");
@@ -72,143 +70,6 @@ void CriticalSection::enter() const noexcept { EnterCriticalSection ((CRITICAL_S
bool CriticalSection::tryEnter() const noexcept { return TryEnterCriticalSection ((CRITICAL_SECTION*) section) != FALSE; }
void CriticalSection::exit() const noexcept { LeaveCriticalSection ((CRITICAL_SECTION*) section); }
-//==============================================================================
-void BEAST_API beast_threadEntryPoint (void*);
-
-static unsigned int __stdcall threadEntryProc (void* userData)
-{
- if (beast_messageWindowHandle != 0)
- AttachThreadInput (GetWindowThreadProcessId (beast_messageWindowHandle, 0),
- GetCurrentThreadId(), TRUE);
-
- beast_threadEntryPoint (userData);
-
- _endthreadex (0);
- return 0;
-}
-
-void Thread::launchThread()
-{
- unsigned int newThreadId;
- threadHandle = (void*) _beginthreadex (0, 0, &threadEntryProc, this, 0, &newThreadId);
- threadId = (ThreadID) newThreadId;
-}
-
-void Thread::closeThreadHandle()
-{
- CloseHandle ((HANDLE) threadHandle);
- threadId = 0;
- threadHandle = 0;
-}
-
-void Thread::killThread()
-{
- if (threadHandle != 0)
- {
- #if BEAST_DEBUG
- OutputDebugStringA ("** Warning - Forced thread termination **\n");
- #endif
- TerminateThread (threadHandle, 0);
- }
-}
-
-void Thread::setCurrentThreadName (const String& name)
-{
- #if BEAST_DEBUG && BEAST_MSVC
- struct
- {
- DWORD dwType;
- LPCSTR szName;
- DWORD dwThreadID;
- DWORD dwFlags;
- } info;
-
- info.dwType = 0x1000;
- info.szName = name.toUTF8();
- info.dwThreadID = GetCurrentThreadId();
- info.dwFlags = 0;
-
- __try
- {
- RaiseException (0x406d1388 /*MS_VC_EXCEPTION*/, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
- }
- __except (EXCEPTION_CONTINUE_EXECUTION)
- {}
- #else
- (void) name;
- #endif
-}
-
-Thread::ThreadID Thread::getCurrentThreadId()
-{
- return (ThreadID) (pointer_sized_int) GetCurrentThreadId();
-}
-
-bool Thread::setThreadPriority (void* handle, int priority)
-{
- int pri = THREAD_PRIORITY_TIME_CRITICAL;
-
- if (priority < 1) pri = THREAD_PRIORITY_IDLE;
- else if (priority < 2) pri = THREAD_PRIORITY_LOWEST;
- else if (priority < 5) pri = THREAD_PRIORITY_BELOW_NORMAL;
- else if (priority < 7) pri = THREAD_PRIORITY_NORMAL;
- else if (priority < 9) pri = THREAD_PRIORITY_ABOVE_NORMAL;
- else if (priority < 10) pri = THREAD_PRIORITY_HIGHEST;
-
- if (handle == 0)
- handle = GetCurrentThread();
-
- return SetThreadPriority (handle, pri) != FALSE;
-}
-
-void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
-{
- SetThreadAffinityMask (GetCurrentThread(), affinityMask);
-}
-
-//==============================================================================
-struct SleepEvent
-{
- SleepEvent() noexcept
- : handle (CreateEvent (nullptr, FALSE, FALSE,
- #if BEAST_DEBUG
- _T("BEAST Sleep Event")))
- #else
- nullptr))
- #endif
- {}
-
- ~SleepEvent() noexcept
- {
- CloseHandle (handle);
- handle = 0;
- }
-
- HANDLE handle;
-};
-
-static SleepEvent sleepEvent;
-
-void BEAST_CALLTYPE Thread::sleep (const int millisecs)
-{
- if (millisecs >= 10 || sleepEvent.handle == 0)
- {
- Sleep ((DWORD) millisecs);
- }
- else
- {
- // unlike Sleep() this is guaranteed to return to the current thread after
- // the time expires, so we'll use this for short waits, which are more likely
- // to need to be accurate
- WaitForSingleObject (sleepEvent.handle, (DWORD) millisecs);
- }
-}
-
-void Thread::yield()
-{
- Sleep (0);
-}
-
//==============================================================================
static int lastProcessPriority = -1;
diff --git a/src/beast/modules/beast_core/threads/ReadWriteMutex.cpp b/src/beast/modules/beast_core/threads/ReadWriteMutex.cpp
deleted file mode 100644
index 6118e4e26..000000000
--- a/src/beast/modules/beast_core/threads/ReadWriteMutex.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- 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.
-*/
-//==============================================================================
-
-ReadWriteMutex::ReadWriteMutex () noexcept
-{
-}
-
-ReadWriteMutex::~ReadWriteMutex () noexcept
-{
-}
-
-void ReadWriteMutex::enterRead () const noexcept
-{
- for (;;)
- {
- // attempt the lock optimistically
- // THIS IS NOT CACHE-FRIENDLY!
- m_readers->addref ();
-
- // is there a writer?
- // THIS IS NOT CACHE-FRIENDLY!
- if (m_writes->isSignaled ())
- {
- // a writer exists, give up the read lock
- m_readers->release ();
-
- // block until the writer is done
- {
- CriticalSection::ScopedLockType lock (m_mutex);
- }
-
- // now try the loop again
- }
- else
- {
- break;
- }
- }
-}
-
-void ReadWriteMutex::exitRead () const noexcept
-{
- m_readers->release ();
-}
-
-void ReadWriteMutex::enterWrite () const noexcept
-{
- // Optimistically acquire the write lock.
- m_writes->addref ();
-
- // Go for the mutex.
- // Another writer might block us here.
- m_mutex.enter ();
-
- // Only one competing writer will get here,
- // but we don't know who, so we have to drain
- // readers no matter what. New readers will be
- // blocked by the mutex.
- //
- if (m_readers->isSignaled ())
- {
- SpinDelay delay;
-
- do
- {
- delay.pause ();
- }
- while (m_readers->isSignaled ());
- }
-}
-
-void ReadWriteMutex::exitWrite () const noexcept
-{
- // Releasing the mutex first and then decrementing the
- // writer count allows another waiting writer to atomically
- // acquire the lock, thus starving readers. This fulfills
- // the write-preferencing requirement.
-
- m_mutex.exit ();
-
- m_writes->release ();
-}
diff --git a/src/beast/modules/beast_core/threads/ReadWriteMutex.h b/src/beast/modules/beast_core/threads/ReadWriteMutex.h
deleted file mode 100644
index 05b87750c..000000000
--- a/src/beast/modules/beast_core/threads/ReadWriteMutex.h
+++ /dev/null
@@ -1,150 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- 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_READWRITEMUTEX_H_INCLUDED
-#define BEAST_READWRITEMUTEX_H_INCLUDED
-
-/*============================================================================*/
-/**
- Multiple consumer, single producer (MCSP) synchronization.
-
- This is an optimized lock for the multiple reader, single writer
- scenario. It provides only a subset of features of the more general
- traditional read/write lock. Specifically, these rules apply:
-
- - A caller cannot hold a read lock while acquiring a write lock.
-
- - Write locks are only recursive with respect to write locks.
-
- - Read locks are only recursive with respect to read locks.
-
- - A write lock cannot be downgraded.
-
- - Writes are preferenced over reads.
-
- For real-time applications, these restrictions are often not an issue.
-
- The implementation is wait-free in the fast path: acquiring read access
- for a lock without contention - just one interlocked increment!
-
- @class ReadWriteMutex
- @ingroup beast_concurrent
-*/
-
-//------------------------------------------------------------------------------
-
-/**
- Scoped read lock for ReadWriteMutex.
-
- @ingroup beast_concurrent
-*/
-template
-struct GenericScopedReadLock : public Uncopyable
-{
- inline explicit GenericScopedReadLock (LockType const& lock) noexcept
-:
- m_lock (lock)
- {
- m_lock.enterRead ();
- }
-
- inline ~GenericScopedReadLock () noexcept
- {
- m_lock.exitRead ();
- }
-
-private:
- LockType const& m_lock;
-};
-
-//------------------------------------------------------------------------------
-
-/**
- Scoped write lock for ReadWriteMutex.
-
- @ingroup beast_concurrent
-*/
-template
-struct GenericScopedWriteLock : public Uncopyable
-{
- inline explicit GenericScopedWriteLock (LockType const& lock) noexcept
-:
- m_lock (lock)
- {
- m_lock.enterWrite ();
- }
-
- inline ~GenericScopedWriteLock () noexcept
- {
- m_lock.exitWrite ();
- }
-
-private:
- LockType const& m_lock;
-};
-
-//------------------------------------------------------------------------------
-
-class BEAST_API ReadWriteMutex
-{
-public:
- /** Provides the type of scoped read lock to use with a ReadWriteMutex. */
- typedef GenericScopedReadLock ScopedReadLockType;
-
- /** Provides the type of scoped write lock to use with a ReadWriteMutex. */
- typedef GenericScopedWriteLock ScopedWriteLockType;
-
- /** Create a ReadWriteMutex */
- ReadWriteMutex () noexcept;
-
- /** Destroy a ReadWriteMutex
-
- If the object is destroyed while a lock is held, the result is
- undefined behavior.
- */
- ~ReadWriteMutex () noexcept;
-
- /** Acquire a read lock.
-
- This is recursive with respect to other read locks. Calling this while
- holding a write lock is undefined.
- */
- void enterRead () const noexcept;
-
- /** Release a previously acquired read lock */
- void exitRead () const noexcept;
-
- /** Acquire a write lock.
-
- This is recursive with respect to other write locks. Calling this while
- holding a read lock is undefined.
- */
- void enterWrite () const noexcept;
-
- /** Release a previously acquired write lock */
- void exitWrite () const noexcept;
-
-private:
- CriticalSection m_mutex;
-
- mutable CacheLine::Padded m_writes;
- mutable CacheLine::Padded m_readers;
-};
-
-#endif
diff --git a/src/beast/modules/beast_core/threads/Thread.cpp b/src/beast/modules/beast_core/threads/Thread.cpp
deleted file mode 100644
index f3ab1eb2b..000000000
--- a/src/beast/modules/beast_core/threads/Thread.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Portions of this file are from JUCE.
- Copyright (c) 2013 - Raw Material Software Ltd.
- Please visit http://www.juce.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.
-*/
-//==============================================================================
-
-Thread::Thread (const String& threadName_)
- : threadName (threadName_),
- threadHandle (nullptr),
- threadId (0),
- threadPriority (5),
- affinityMask (0),
- shouldExit (false)
-{
-}
-
-Thread::~Thread()
-{
- /* If your thread class's destructor has been called without first stopping the thread, that
- means that this partially destructed object is still performing some work - and that's
- probably a Bad Thing!
-
- To avoid this type of nastiness, always make sure you call stopThread() before or during
- your subclass's destructor.
- */
- check_precondition (! isThreadRunning());
-
- stopThread ();
-}
-
-//==============================================================================
-// Use a ref-counted object to hold this shared data, so that it can outlive its static
-// shared pointer when threads are still running during static shutdown.
-struct CurrentThreadHolder : public SharedObject
-{
- CurrentThreadHolder() noexcept {}
-
- typedef SharedPtr Ptr;
- ThreadLocalValue value;
-};
-
-static char currentThreadHolderLock [sizeof (SpinLock)]; // (statically initialised to zeros).
-
-static SpinLock* castToSpinLockWithoutAliasingWarning (void* s)
-{
- return static_cast (s);
-}
-
-static CurrentThreadHolder::Ptr getCurrentThreadHolder()
-{
- static CurrentThreadHolder::Ptr currentThreadHolder;
- SpinLock::ScopedLockType lock (*castToSpinLockWithoutAliasingWarning (currentThreadHolderLock));
-
- if (currentThreadHolder == nullptr)
- currentThreadHolder = new CurrentThreadHolder();
-
- return currentThreadHolder;
-}
-
-void Thread::threadEntryPoint()
-{
- const CurrentThreadHolder::Ptr currentThreadHolder (getCurrentThreadHolder());
- currentThreadHolder->value = this;
-
- if (threadName.isNotEmpty())
- setCurrentThreadName (threadName);
-
- if (startSuspensionEvent.wait (10000))
- {
- bassert (getCurrentThreadId() == threadId);
-
- if (affinityMask != 0)
- setCurrentThreadAffinityMask (affinityMask);
-
- run();
- }
-
- currentThreadHolder->value.releaseCurrentThreadStorage();
- closeThreadHandle();
-}
-
-// used to wrap the incoming call from the platform-specific code
-void BEAST_API beast_threadEntryPoint (void* userData)
-{
- static_cast (userData)->threadEntryPoint();
-}
-
-//==============================================================================
-void Thread::startThread()
-{
- const ScopedLock sl (startStopLock);
-
- shouldExit = false;
-
- if (threadHandle == nullptr)
- {
- launchThread();
- setThreadPriority (threadHandle, threadPriority);
- startSuspensionEvent.signal();
- }
-}
-
-void Thread::startThread (const int priority)
-{
- const ScopedLock sl (startStopLock);
-
- if (threadHandle == nullptr)
- {
- threadPriority = priority;
- startThread();
- }
- else
- {
- setPriority (priority);
- }
-}
-
-bool Thread::isThreadRunning() const
-{
- return threadHandle != nullptr;
-}
-
-Thread* Thread::getCurrentThread()
-{
- return getCurrentThreadHolder()->value.get();
-}
-
-//==============================================================================
-void Thread::signalThreadShouldExit()
-{
- shouldExit = true;
-}
-
-bool Thread::waitForThreadToExit (const int timeOutMilliseconds) const
-{
- // Doh! So how exactly do you expect this thread to wait for itself to stop??
- bassert (getThreadId() != getCurrentThreadId() || getCurrentThreadId() == 0);
-
- const uint32 timeoutEnd = Time::getMillisecondCounter() + (uint32) timeOutMilliseconds;
-
- while (isThreadRunning())
- {
- if (timeOutMilliseconds >= 0 && Time::getMillisecondCounter() > timeoutEnd)
- return false;
-
- sleep (2);
- }
-
- return true;
-}
-
-bool Thread::stopThread (const int timeOutMilliseconds)
-{
- bool cleanExit = true;
-
- // agh! You can't stop the thread that's calling this method! How on earth
- // would that work??
- bassert (getCurrentThreadId() != getThreadId());
-
- const ScopedLock sl (startStopLock);
-
- if (isThreadRunning())
- {
- signalThreadShouldExit();
- notify();
-
- if (timeOutMilliseconds != 0)
- {
- cleanExit = waitForThreadToExit (timeOutMilliseconds);
- }
-
- if (isThreadRunning())
- {
- bassert (! cleanExit);
-
- // very bad karma if this point is reached, as there are bound to be
- // locks and events left in silly states when a thread is killed by force..
- killThread();
-
- threadHandle = nullptr;
- threadId = 0;
-
- cleanExit = false;
- }
- else
- {
- cleanExit = true;
- }
- }
-
- return cleanExit;
-}
-
-void Thread::stopThreadAsync ()
-{
- const ScopedLock sl (startStopLock);
-
- if (isThreadRunning())
- {
- signalThreadShouldExit();
- notify();
- }
-}
-
-//==============================================================================
-bool Thread::setPriority (const int newPriority)
-{
- // NB: deadlock possible if you try to set the thread prio from the thread itself,
- // so using setCurrentThreadPriority instead in that case.
- if (getCurrentThreadId() == getThreadId())
- return setCurrentThreadPriority (newPriority);
-
- const ScopedLock sl (startStopLock);
-
- if (setThreadPriority (threadHandle, newPriority))
- {
- threadPriority = newPriority;
- return true;
- }
-
- return false;
-}
-
-bool Thread::setCurrentThreadPriority (const int newPriority)
-{
- return setThreadPriority (0, newPriority);
-}
-
-void Thread::setAffinityMask (const uint32 newAffinityMask)
-{
- affinityMask = newAffinityMask;
-}
-
-//==============================================================================
-bool Thread::wait (const int timeOutMilliseconds) const
-{
- return defaultEvent.wait (timeOutMilliseconds);
-}
-
-void Thread::notify() const
-{
- defaultEvent.signal();
-}
-
-//==============================================================================
-void SpinLock::enter() const noexcept
-{
- if (! tryEnter())
- {
- for (int i = 20; --i >= 0;)
- if (tryEnter())
- return;
-
- while (! tryEnter())
- Thread::yield();
- }
-}
-
-//==============================================================================
-
-class AtomicTests : public UnitTest
-{
-public:
- AtomicTests() : UnitTest ("Atomic", "beast") {}
-
- void runTest()
- {
- beginTestCase ("Misc");
-
- char a1[7];
- expect (numElementsInArray(a1) == 7);
- int a2[3];
- expect (numElementsInArray(a2) == 3);
-
- expect (ByteOrder::swap ((uint16) 0x1122) == 0x2211);
- expect (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);
- expect (ByteOrder::swap ((uint64) literal64bit (0x1122334455667788)) == literal64bit (0x8877665544332211));
-
- beginTestCase ("int");
- AtomicTester ::testInteger (*this);
- beginTestCase ("unsigned int");
- AtomicTester ::testInteger (*this);
- beginTestCase ("int32");
- AtomicTester ::testInteger (*this);
- beginTestCase ("uint32");
- AtomicTester ::testInteger (*this);
- beginTestCase ("long");
- AtomicTester ::testInteger (*this);
- beginTestCase ("void*");
- AtomicTester ::testInteger (*this);
- beginTestCase ("int*");
- AtomicTester ::testInteger (*this);
- beginTestCase ("float");
- AtomicTester ::testFloat (*this);
- #if ! BEAST_64BIT_ATOMICS_UNAVAILABLE // 64-bit intrinsics aren't available on some old platforms
- beginTestCase ("int64");
- AtomicTester ::testInteger (*this);
- beginTestCase ("uint64");
- AtomicTester ::testInteger (*this);
- beginTestCase ("double");
- AtomicTester ::testFloat (*this);
- #endif
- }
-
- template
- class AtomicTester
- {
- public:
- AtomicTester() {}
-
- static void testInteger (UnitTest& test)
- {
- Atomic a, b;
- a.set ((Type) 10);
- test.expect (a.value == (Type) 10);
- test.expect (a.get() == (Type) 10);
- a += (Type) 15;
- test.expect (a.get() == (Type) 25);
- memoryBarrier();
- a -= (Type) 5;
- test.expect (a.get() == (Type) 20);
- test.expect (++a == (Type) 21);
- ++a;
- test.expect (--a == (Type) 21);
- test.expect (a.get() == (Type) 21);
- memoryBarrier();
-
- testFloat (test);
- }
-
- static void testFloat (UnitTest& test)
- {
- Atomic a, b;
- a = (Type) 21;
- memoryBarrier();
-
- /* These are some simple test cases to check the atomics - let me know
- if any of these assertions fail on your system!
- */
- test.expect (a.get() == (Type) 21);
- test.expect (a.compareAndSetValue ((Type) 100, (Type) 50) == (Type) 21);
- test.expect (a.get() == (Type) 21);
- test.expect (a.compareAndSetValue ((Type) 101, a.get()) == (Type) 21);
- test.expect (a.get() == (Type) 101);
- test.expect (! a.compareAndSetBool ((Type) 300, (Type) 200));
- test.expect (a.get() == (Type) 101);
- test.expect (a.compareAndSetBool ((Type) 200, a.get()));
- test.expect (a.get() == (Type) 200);
-
- test.expect (a.exchange ((Type) 300) == (Type) 200);
- test.expect (a.get() == (Type) 300);
-
- b = a;
- test.expect (b.get() == a.get());
- }
- };
-};
-
-static AtomicTests atomicTests;
diff --git a/src/beast/modules/beast_core/threads/ThreadPool.cpp b/src/beast/modules/beast_core/threads/ThreadPool.cpp
deleted file mode 100644
index 71354bad0..000000000
--- a/src/beast/modules/beast_core/threads/ThreadPool.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Portions of this file are from JUCE.
- Copyright (c) 2013 - Raw Material Software Ltd.
- Please visit http://www.juce.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.
-*/
-//==============================================================================
-
-ThreadPoolJob::ThreadPoolJob (const String& name)
- : jobName (name),
- pool (nullptr),
- shouldStop (false),
- isActive (false),
- shouldBeDeleted (false)
-{
-}
-
-ThreadPoolJob::~ThreadPoolJob()
-{
- // you mustn't delete a job while it's still in a pool! Use ThreadPool::removeJob()
- // to remove it first!
- bassert (pool == nullptr || ! pool->contains (this));
-}
-
-String ThreadPoolJob::getJobName() const
-{
- return jobName;
-}
-
-void ThreadPoolJob::setJobName (const String& newName)
-{
- jobName = newName;
-}
-
-void ThreadPoolJob::signalJobShouldExit()
-{
- shouldStop = true;
-}
-
-//==============================================================================
-class ThreadPool::ThreadPoolThread
- : public Thread
- , LeakChecked
-{
-public:
- ThreadPoolThread (ThreadPool& pool_)
- : Thread ("Pool"),
- pool (pool_)
- {
- }
-
- void run() override
- {
- while (! threadShouldExit())
- {
- if (! pool.runNextJob())
- wait (500);
- }
- }
-
-private:
- ThreadPool& pool;
-};
-
-//==============================================================================
-ThreadPool::ThreadPool (const int numThreads)
-{
- bassert (numThreads > 0); // not much point having a pool without any threads!
-
- createThreads (numThreads);
-}
-
-ThreadPool::ThreadPool()
-{
- createThreads (SystemStats::getNumCpus());
-}
-
-ThreadPool::~ThreadPool()
-{
- removeAllJobs (true, 5000);
- stopThreads();
-}
-
-void ThreadPool::createThreads (int numThreads)
-{
- for (int i = bmax (1, numThreads); --i >= 0;)
- threads.add (new ThreadPoolThread (*this));
-
- for (int i = threads.size(); --i >= 0;)
- threads.getUnchecked(i)->startThread();
-}
-
-void ThreadPool::stopThreads()
-{
- for (int i = threads.size(); --i >= 0;)
- threads.getUnchecked(i)->signalThreadShouldExit();
-
- for (int i = threads.size(); --i >= 0;)
- threads.getUnchecked(i)->stopThread (500);
-}
-
-void ThreadPool::addJob (ThreadPoolJob* const job, const bool deleteJobWhenFinished)
-{
- bassert (job != nullptr);
- bassert (job->pool == nullptr);
-
- if (job->pool == nullptr)
- {
- job->pool = this;
- job->shouldStop = false;
- job->isActive = false;
- job->shouldBeDeleted = deleteJobWhenFinished;
-
- {
- const ScopedLock sl (lock);
- jobs.add (job);
- }
-
- for (int i = threads.size(); --i >= 0;)
- threads.getUnchecked(i)->notify();
- }
-}
-
-int ThreadPool::getNumJobs() const
-{
- return jobs.size();
-}
-
-ThreadPoolJob* ThreadPool::getJob (const int index) const
-{
- const ScopedLock sl (lock);
- return jobs [index];
-}
-
-bool ThreadPool::contains (const ThreadPoolJob* const job) const
-{
- const ScopedLock sl (lock);
- return jobs.contains (const_cast (job));
-}
-
-bool ThreadPool::isJobRunning (const ThreadPoolJob* const job) const
-{
- const ScopedLock sl (lock);
- return jobs.contains (const_cast (job)) && job->isActive;
-}
-
-bool ThreadPool::waitForJobToFinish (const ThreadPoolJob* const job,
- const int timeOutMs) const
-{
- if (job != nullptr)
- {
- const uint32 start = Time::getMillisecondCounter();
-
- while (contains (job))
- {
- if (timeOutMs >= 0 && Time::getMillisecondCounter() >= start + (uint32) timeOutMs)
- return false;
-
- jobFinishedSignal.wait (2);
- }
- }
-
- return true;
-}
-
-bool ThreadPool::removeJob (ThreadPoolJob* const job,
- const bool interruptIfRunning,
- const int timeOutMs)
-{
- bool dontWait = true;
- OwnedArray deletionList;
-
- if (job != nullptr)
- {
- const ScopedLock sl (lock);
-
- if (jobs.contains (job))
- {
- if (job->isActive)
- {
- if (interruptIfRunning)
- job->signalJobShouldExit();
-
- dontWait = false;
- }
- else
- {
- jobs.removeFirstMatchingValue (job);
- addToDeleteList (deletionList, job);
- }
- }
- }
-
- return dontWait || waitForJobToFinish (job, timeOutMs);
-}
-
-bool ThreadPool::removeAllJobs (const bool interruptRunningJobs, const int timeOutMs,
- ThreadPool::JobSelector* selectedJobsToRemove)
-{
- Array jobsToWaitFor;
-
- {
- OwnedArray deletionList;
-
- {
- const ScopedLock sl (lock);
-
- for (int i = jobs.size(); --i >= 0;)
- {
- ThreadPoolJob* const job = jobs.getUnchecked(i);
-
- if (selectedJobsToRemove == nullptr || selectedJobsToRemove->isJobSuitable (job))
- {
- if (job->isActive)
- {
- jobsToWaitFor.add (job);
-
- if (interruptRunningJobs)
- job->signalJobShouldExit();
- }
- else
- {
- jobs.remove (i);
- addToDeleteList (deletionList, job);
- }
- }
- }
- }
- }
-
- const uint32 start = Time::getMillisecondCounter();
-
- for (;;)
- {
- for (int i = jobsToWaitFor.size(); --i >= 0;)
- {
- ThreadPoolJob* const job = jobsToWaitFor.getUnchecked (i);
-
- if (! isJobRunning (job))
- jobsToWaitFor.remove (i);
- }
-
- if (jobsToWaitFor.size() == 0)
- break;
-
- if (timeOutMs >= 0 && Time::getMillisecondCounter() >= start + (uint32) timeOutMs)
- return false;
-
- jobFinishedSignal.wait (20);
- }
-
- return true;
-}
-
-StringArray ThreadPool::getNamesOfAllJobs (const bool onlyReturnActiveJobs) const
-{
- StringArray s;
- const ScopedLock sl (lock);
-
- for (int i = 0; i < jobs.size(); ++i)
- {
- const ThreadPoolJob* const job = jobs.getUnchecked(i);
- if (job->isActive || ! onlyReturnActiveJobs)
- s.add (job->getJobName());
- }
-
- return s;
-}
-
-bool ThreadPool::setThreadPriorities (const int newPriority)
-{
- bool ok = true;
-
- for (int i = threads.size(); --i >= 0;)
- if (! threads.getUnchecked(i)->setPriority (newPriority))
- ok = false;
-
- return ok;
-}
-
-ThreadPoolJob* ThreadPool::pickNextJobToRun()
-{
- OwnedArray deletionList;
-
- {
- const ScopedLock sl (lock);
-
- for (int i = 0; i < jobs.size(); ++i)
- {
- ThreadPoolJob* job = jobs[i];
-
- if (job != nullptr && ! job->isActive)
- {
- if (job->shouldStop)
- {
- jobs.remove (i);
- addToDeleteList (deletionList, job);
- --i;
- continue;
- }
-
- job->isActive = true;
- return job;
- }
- }
- }
-
- return nullptr;
-}
-
-bool ThreadPool::runNextJob()
-{
- ThreadPoolJob* const job = pickNextJobToRun();
-
- if (job == nullptr)
- return false;
-
- ThreadPoolJob::JobStatus result = ThreadPoolJob::jobHasFinished;
-
- result = job->runJob();
-
- OwnedArray deletionList;
-
- {
- const ScopedLock sl (lock);
-
- if (jobs.contains (job))
- {
- job->isActive = false;
-
- if (result != ThreadPoolJob::jobNeedsRunningAgain || job->shouldStop)
- {
- jobs.removeFirstMatchingValue (job);
- addToDeleteList (deletionList, job);
-
- jobFinishedSignal.signal();
- }
- else
- {
- // move the job to the end of the queue if it wants another go
- jobs.move (jobs.indexOf (job), -1);
- }
- }
- }
-
- return true;
-}
-
-void ThreadPool::addToDeleteList (OwnedArray& deletionList, ThreadPoolJob* const job) const
-{
- job->shouldStop = true;
- job->pool = nullptr;
-
- if (job->shouldBeDeleted)
- deletionList.add (job);
-}
diff --git a/src/beast/modules/beast_core/threads/ThreadPool.h b/src/beast/modules/beast_core/threads/ThreadPool.h
deleted file mode 100644
index c2c27783a..000000000
--- a/src/beast/modules/beast_core/threads/ThreadPool.h
+++ /dev/null
@@ -1,304 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Portions of this file are from JUCE.
- Copyright (c) 2013 - Raw Material Software Ltd.
- Please visit http://www.juce.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_THREADPOOL_H_INCLUDED
-#define BEAST_THREADPOOL_H_INCLUDED
-
-class ThreadPool;
-class ThreadPoolThread;
-
-//==============================================================================
-/**
- A task that is executed by a ThreadPool object.
-
- A ThreadPool keeps a list of ThreadPoolJob objects which are executed by
- its threads.
-
- The runJob() method needs to be implemented to do the task, and if the code that
- does the work takes a significant time to run, it must keep checking the shouldExit()
- method to see if something is trying to interrupt the job. If shouldExit() returns
- true, the runJob() method must return immediately.
-
- @see ThreadPool, Thread
-*/
-class BEAST_API ThreadPoolJob : LeakChecked , public Uncopyable
-{
-public:
- //==============================================================================
- /** Creates a thread pool job object.
- After creating your job, add it to a thread pool with ThreadPool::addJob().
- */
- explicit ThreadPoolJob (const String& name);
-
- /** Destructor. */
- virtual ~ThreadPoolJob();
-
- //==============================================================================
- /** Returns the name of this job.
- @see setJobName
- */
- String getJobName() const;
-
- /** Changes the job's name.
- @see getJobName
- */
- void setJobName (const String& newName);
-
- //==============================================================================
- /** These are the values that can be returned by the runJob() method.
- */
- enum JobStatus
- {
- jobHasFinished = 0, /**< indicates that the job has finished and can be
- removed from the pool. */
-
- jobNeedsRunningAgain /**< indicates that the job would like to be called
- again when a thread is free. */
- };
-
- /** Peforms the actual work that this job needs to do.
-
- Your subclass must implement this method, in which is does its work.
-
- If the code in this method takes a significant time to run, it must repeatedly check
- the shouldExit() method to see if something is trying to interrupt the job.
- If shouldExit() ever returns true, the runJob() method must return immediately.
-
- If this method returns jobHasFinished, then the job will be removed from the pool
- immediately. If it returns jobNeedsRunningAgain, then the job will be left in the
- pool and will get a chance to run again as soon as a thread is free.
-
- @see shouldExit()
- */
- virtual JobStatus runJob() = 0;
-
-
- //==============================================================================
- /** Returns true if this job is currently running its runJob() method. */
- bool isRunning() const noexcept { return isActive; }
-
- /** Returns true if something is trying to interrupt this job and make it stop.
-
- Your runJob() method must call this whenever it gets a chance, and if it ever
- returns true, the runJob() method must return immediately.
-
- @see signalJobShouldExit()
- */
- bool shouldExit() const noexcept { return shouldStop; }
-
- /** Calling this will cause the shouldExit() method to return true, and the job
- should (if it's been implemented correctly) stop as soon as possible.
-
- @see shouldExit()
- */
- void signalJobShouldExit();
-
- //==============================================================================
-private:
- friend class ThreadPool;
- friend class ThreadPoolThread;
- String jobName;
- ThreadPool* pool;
- bool shouldStop, isActive, shouldBeDeleted;
-};
-
-
-//==============================================================================
-/**
- A set of threads that will run a list of jobs.
-
- When a ThreadPoolJob object is added to the ThreadPool's list, its runJob() method
- will be called by the next pooled thread that becomes free.
-
- @see ThreadPoolJob, Thread
-*/
-class BEAST_API ThreadPool : LeakChecked , public Uncopyable
-{
-public:
- //==============================================================================
- /** Creates a thread pool.
- Once you've created a pool, you can give it some jobs by calling addJob().
- @param numberOfThreads the number of threads to run. These will be started
- immediately, and will run until the pool is deleted.
- */
- ThreadPool (int numberOfThreads);
-
- /** Creates a thread pool with one thread per CPU core.
- Once you've created a pool, you can give it some jobs by calling addJob().
- If you want to specify the number of threads, use the other constructor; this
- one creates a pool which has one thread for each CPU core.
- @see SystemStats::getNumCpus()
- */
- ThreadPool();
-
- /** Destructor.
-
- This will attempt to remove all the jobs before deleting, but if you want to
- specify a timeout, you should call removeAllJobs() explicitly before deleting
- the pool.
- */
- ~ThreadPool();
-
- //==============================================================================
- /** A callback class used when you need to select which ThreadPoolJob objects are suitable
- for some kind of operation.
- @see ThreadPool::removeAllJobs
- */
- class BEAST_API JobSelector
- {
- public:
- virtual ~JobSelector() {}
-
- /** Should return true if the specified thread matches your criteria for whatever
- operation that this object is being used for.
-
- Any implementation of this method must be extremely fast and thread-safe!
- */
- virtual bool isJobSuitable (ThreadPoolJob* job) = 0;
- };
-
- //==============================================================================
- /** Adds a job to the queue.
-
- Once a job has been added, then the next time a thread is free, it will run
- the job's ThreadPoolJob::runJob() method. Depending on the return value of the
- runJob() method, the pool will either remove the job from the pool or add it to
- the back of the queue to be run again.
-
- If deleteJobWhenFinished is true, then the job object will be owned and deleted by
- the pool when not needed - if you do this, make sure that your object's destructor
- is thread-safe.
-
- If deleteJobWhenFinished is false, the pointer will be used but not deleted, and
- the caller is responsible for making sure the object is not deleted before it has
- been removed from the pool.
- */
- void addJob (ThreadPoolJob* job,
- bool deleteJobWhenFinished);
-
- /** Tries to remove a job from the pool.
-
- If the job isn't yet running, this will simply remove it. If it is running, it
- will wait for it to finish.
-
- If the timeout period expires before the job finishes running, then the job will be
- left in the pool and this will return false. It returns true if the job is sucessfully
- stopped and removed.
-
- @param job the job to remove
- @param interruptIfRunning if true, then if the job is currently busy, its
- ThreadPoolJob::signalJobShouldExit() method will be called to try
- to interrupt it. If false, then if the job will be allowed to run
- until it stops normally (or the timeout expires)
- @param timeOutMilliseconds the length of time this method should wait for the job to finish
- before giving up and returning false
- */
- bool removeJob (ThreadPoolJob* job,
- bool interruptIfRunning,
- int timeOutMilliseconds);
-
- /** Tries to remove all jobs from the pool.
-
- @param interruptRunningJobs if true, then all running jobs will have their ThreadPoolJob::signalJobShouldExit()
- methods called to try to interrupt them
- @param timeOutMilliseconds the length of time this method should wait for all the jobs to finish
- before giving up and returning false
- @param selectedJobsToRemove if this is non-zero, the JobSelector object is asked to decide which
- jobs should be removed. If it is zero, all jobs are removed
- @returns true if all jobs are successfully stopped and removed; false if the timeout period
- expires while waiting for one or more jobs to stop
- */
- bool removeAllJobs (bool interruptRunningJobs,
- int timeOutMilliseconds,
- JobSelector* selectedJobsToRemove = nullptr);
-
- /** Returns the number of jobs currently running or queued.
- */
- int getNumJobs() const;
-
- /** Returns one of the jobs in the queue.
-
- Note that this can be a very volatile list as jobs might be continuously getting shifted
- around in the list, and this method may return 0 if the index is currently out-of-range.
- */
- ThreadPoolJob* getJob (int index) const;
-
- /** Returns true if the given job is currently queued or running.
-
- @see isJobRunning()
- */
- bool contains (const ThreadPoolJob* job) const;
-
- /** Returns true if the given job is currently being run by a thread.
- */
- bool isJobRunning (const ThreadPoolJob* job) const;
-
- /** Waits until a job has finished running and has been removed from the pool.
-
- This will wait until the job is no longer in the pool - i.e. until its
- runJob() method returns ThreadPoolJob::jobHasFinished.
-
- If the timeout period expires before the job finishes, this will return false;
- it returns true if the job has finished successfully.
- */
- bool waitForJobToFinish (const ThreadPoolJob* job,
- int timeOutMilliseconds) const;
-
- /** Returns a list of the names of all the jobs currently running or queued.
- If onlyReturnActiveJobs is true, only the ones currently running are returned.
- */
- StringArray getNamesOfAllJobs (bool onlyReturnActiveJobs) const;
-
- /** Changes the priority of all the threads.
-
- This will call Thread::setPriority() for each thread in the pool.
- May return false if for some reason the priority can't be changed.
- */
- bool setThreadPriorities (int newPriority);
-
-
-private:
- //==============================================================================
- Array jobs;
-
- class ThreadPoolThread;
- friend class ThreadPoolThread;
- friend class OwnedArray ;
- OwnedArray threads;
-
- CriticalSection lock;
- WaitableEvent jobFinishedSignal;
-
- bool runNextJob();
- ThreadPoolJob* pickNextJobToRun();
- void addToDeleteList (OwnedArray&, ThreadPoolJob*) const;
- void createThreads (int numThreads);
- void stopThreads();
-
- // Note that this method has changed, and no longer has a parameter to indicate
- // whether the jobs should be deleted - see the new method for details.
- void removeAllJobs (bool, int, bool);
-};
-
-
-#endif // BEAST_THREADPOOL_H_INCLUDED
diff --git a/src/beast/modules/beast_core/threads/TimeSliceThread.cpp b/src/beast/modules/beast_core/threads/TimeSliceThread.cpp
deleted file mode 100644
index 106e7084d..000000000
--- a/src/beast/modules/beast_core/threads/TimeSliceThread.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Portions of this file are from JUCE.
- Copyright (c) 2013 - Raw Material Software Ltd.
- Please visit http://www.juce.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.
-*/
-//==============================================================================
-
-TimeSliceThread::TimeSliceThread (const String& name)
- : Thread (name),
- clientBeingCalled (nullptr)
-{
-}
-
-TimeSliceThread::~TimeSliceThread()
-{
- stopThread (2000);
-}
-
-//==============================================================================
-void TimeSliceThread::addTimeSliceClient (TimeSliceClient* const client, int millisecondsBeforeStarting)
-{
- if (client != nullptr)
- {
- const ScopedLock sl (listLock);
- client->nextCallTime = Time::getCurrentTime() + RelativeTime::milliseconds (millisecondsBeforeStarting);
- clients.addIfNotAlreadyThere (client);
- notify();
- }
-}
-
-void TimeSliceThread::removeTimeSliceClient (TimeSliceClient* const client)
-{
- const ScopedLock sl1 (listLock);
-
- // if there's a chance we're in the middle of calling this client, we need to
- // also lock the outer lock..
- if (clientBeingCalled == client)
- {
- const ScopedUnlock ul (listLock); // unlock first to get the order right..
-
- const ScopedLock sl2 (callbackLock);
- const ScopedLock sl3 (listLock);
-
- clients.removeFirstMatchingValue (client);
- }
- else
- {
- clients.removeFirstMatchingValue (client);
- }
-}
-
-void TimeSliceThread::moveToFrontOfQueue (TimeSliceClient* client)
-{
- const ScopedLock sl (listLock);
-
- if (clients.contains (client))
- {
- client->nextCallTime = Time::getCurrentTime();
- notify();
- }
-}
-
-int TimeSliceThread::getNumClients() const
-{
- return clients.size();
-}
-
-TimeSliceClient* TimeSliceThread::getClient (const int i) const
-{
- const ScopedLock sl (listLock);
- return clients [i];
-}
-
-//==============================================================================
-TimeSliceClient* TimeSliceThread::getNextClient (int index) const
-{
- Time soonest;
- TimeSliceClient* client = nullptr;
-
- for (int i = clients.size(); --i >= 0;)
- {
- TimeSliceClient* const c = clients.getUnchecked ((i + index) % clients.size());
-
- if (client == nullptr || c->nextCallTime < soonest)
- {
- client = c;
- soonest = c->nextCallTime;
- }
- }
-
- return client;
-}
-
-void TimeSliceThread::run()
-{
- int index = 0;
-
- while (! threadShouldExit())
- {
- int timeToWait = 500;
-
- {
- Time nextClientTime;
-
- {
- const ScopedLock sl2 (listLock);
-
- index = clients.size() > 0 ? ((index + 1) % clients.size()) : 0;
-
- if (TimeSliceClient* const firstClient = getNextClient (index))
- nextClientTime = firstClient->nextCallTime;
- }
-
- const Time now (Time::getCurrentTime());
-
- if (nextClientTime > now)
- {
- timeToWait = (int) bmin ((int64) 500, (nextClientTime - now).inMilliseconds());
- }
- else
- {
- timeToWait = index == 0 ? 1 : 0;
-
- const ScopedLock sl (callbackLock);
-
- {
- const ScopedLock sl2 (listLock);
- clientBeingCalled = getNextClient (index);
- }
-
- if (clientBeingCalled != nullptr)
- {
- const int msUntilNextCall = clientBeingCalled->useTimeSlice();
-
- const ScopedLock sl2 (listLock);
-
- if (msUntilNextCall >= 0)
- clientBeingCalled->nextCallTime = now + RelativeTime::milliseconds (msUntilNextCall);
- else
- clients.removeFirstMatchingValue (clientBeingCalled);
-
- clientBeingCalled = nullptr;
- }
- }
- }
-
- if (timeToWait > 0)
- wait (timeToWait);
- }
-}
diff --git a/src/beast/modules/beast_core/threads/TimeSliceThread.h b/src/beast/modules/beast_core/threads/TimeSliceThread.h
deleted file mode 100644
index 566b398c2..000000000
--- a/src/beast/modules/beast_core/threads/TimeSliceThread.h
+++ /dev/null
@@ -1,143 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Portions of this file are from JUCE.
- Copyright (c) 2013 - Raw Material Software Ltd.
- Please visit http://www.juce.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_TIMESLICETHREAD_H_INCLUDED
-#define BEAST_TIMESLICETHREAD_H_INCLUDED
-
-class TimeSliceThread;
-
-//==============================================================================
-/**
- Used by the TimeSliceThread class.
-
- To register your class with a TimeSliceThread, derive from this class and
- use the TimeSliceThread::addTimeSliceClient() method to add it to the list.
-
- Make sure you always call TimeSliceThread::removeTimeSliceClient() before
- deleting your client!
-
- @see TimeSliceThread
-*/
-class BEAST_API TimeSliceClient
-{
-public:
- /** Destructor. */
- virtual ~TimeSliceClient() {}
-
- /** Called back by a TimeSliceThread.
-
- When you register this class with it, a TimeSliceThread will repeatedly call
- this method.
-
- The implementation of this method should use its time-slice to do something that's
- quick - never block for longer than absolutely necessary.
-
- @returns Your method should return the number of milliseconds which it would like to wait before being called
- again. Returning 0 will make the thread call again as soon as possible (after possibly servicing
- other busy clients). If you return a value below zero, your client will be removed from the list of clients,
- and won't be called again. The value you specify isn't a guaranteee, and is only used as a hint by the
- thread - the actual time before the next callback may be more or less than specified.
- You can force the TimeSliceThread to wake up and poll again immediately by calling its notify() method.
- */
- virtual int useTimeSlice() = 0;
-
-
-private:
- friend class TimeSliceThread;
- Time nextCallTime;
-};
-
-
-//==============================================================================
-/**
- A thread that keeps a list of clients, and calls each one in turn, giving them
- all a chance to run some sort of short task.
-
- @see TimeSliceClient, Thread
-*/
-class BEAST_API TimeSliceThread
- : public Thread
- , LeakChecked
-{
-public:
- //==============================================================================
- /**
- Creates a TimeSliceThread.
-
- When first created, the thread is not running. Use the startThread()
- method to start it.
- */
- explicit TimeSliceThread (const String& threadName);
-
- /** Destructor.
-
- Deleting a Thread object that is running will only give the thread a
- brief opportunity to stop itself cleanly, so it's recommended that you
- should always call stopThread() with a decent timeout before deleting,
- to avoid the thread being forcibly killed (which is a Bad Thing).
- */
- ~TimeSliceThread();
-
- //==============================================================================
- /** Adds a client to the list.
-
- The client's callbacks will start after the number of milliseconds specified
- by millisecondsBeforeStarting (and this may happen before this method has returned).
- */
- void addTimeSliceClient (TimeSliceClient* client, int millisecondsBeforeStarting = 0);
-
- /** Removes a client from the list.
-
- This method will make sure that all callbacks to the client have completely
- finished before the method returns.
- */
- void removeTimeSliceClient (TimeSliceClient* client);
-
- /** If the given client is waiting in the queue, it will be moved to the front
- and given a time-slice as soon as possible.
- If the specified client has not been added, nothing will happen.
- */
- void moveToFrontOfQueue (TimeSliceClient* client);
-
- /** Returns the number of registered clients. */
- int getNumClients() const;
-
- /** Returns one of the registered clients. */
- TimeSliceClient* getClient (int index) const;
-
- //==============================================================================
- #ifndef DOXYGEN
- void run() override;
- #endif
-
- //==============================================================================
-private:
- CriticalSection callbackLock, listLock;
- Array clients;
- TimeSliceClient* clientBeingCalled;
-
- TimeSliceClient* getNextClient (int index) const;
-};
-
-
-#endif // BEAST_TIMESLICETHREAD_H_INCLUDED
diff --git a/src/ripple/beast/ripple_beast.cpp b/src/ripple/beast/ripple_beast.cpp
index 1510cda2f..876649467 100644
--- a/src/ripple/beast/ripple_beast.cpp
+++ b/src/ripple/beast/ripple_beast.cpp
@@ -42,6 +42,7 @@
#include "../beast/beast/crypto/Crypto.cpp"
#include "../beast/beast/http/HTTP.cpp"
#include "../beast/beast/net/Net.cpp"
+#include "../beast/beast/smart_ptr/SmartPtr.cpp"
#include "../beast/beast/strings/Strings.cpp"
-#include "../beast/beast/thread/Thread.cpp"
+#include "../beast/beast/threads/Threads.cpp"
#include "../beast/beast/utility/Utility.cpp"