diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj
index 657a854f91..38133a41f6 100644
--- a/Builds/VisualStudio2012/beast.vcxproj
+++ b/Builds/VisualStudio2012/beast.vcxproj
@@ -160,6 +160,7 @@
+
@@ -333,7 +334,6 @@
-
@@ -511,6 +511,12 @@
true
true
+
+ true
+ true
+ true
+ true
+
true
diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters
index 6d8a46ed81..b5ca3dc0e5 100644
--- a/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -512,9 +512,6 @@
beast_core\threads
-
- beast_core\threads
-
beast_core\time
@@ -1239,6 +1236,9 @@
beast\chrono
+
+ beast\thread
+
@@ -1787,6 +1787,9 @@
beast\chrono\impl
+
+ beast\thread\impl
+
diff --git a/beast/Thread.h b/beast/Thread.h
index bc3e9428a2..208caed58c 100644
--- a/beast/Thread.h
+++ b/beast/Thread.h
@@ -26,5 +26,6 @@
#include "thread/SharedLockGuard.h"
#include "thread/SharedMutexAdapter.h"
#include "thread/SharedData.h"
+#include "thread/WaitableEvent.h"
#endif
diff --git a/beast/chrono/CPUMeter.h b/beast/chrono/CPUMeter.h
index 8a02b591c2..4040e13822 100644
--- a/beast/chrono/CPUMeter.h
+++ b/beast/chrono/CPUMeter.h
@@ -21,7 +21,7 @@
#define BEAST_CHRONO_CPUMETER_H_INCLUDED
#include "RelativeTime.h"
-#include "SCopedTimeInterval.h"
+#include "ScopedTimeInterval.h"
#include "../thread/SharedData.h"
#include "../Atomic.h"
@@ -120,7 +120,7 @@ private:
void advance ()
{
usage += history [index];
- index = (++index) % numberOfAggregates;
+ index = (index+1) % numberOfAggregates;
usage -= history [index];
history [index].clear ();
}
diff --git a/beast/thread/Thread.cpp b/beast/thread/Thread.cpp
index 79ff63a23e..d44ea8210c 100644
--- a/beast/thread/Thread.cpp
+++ b/beast/thread/Thread.cpp
@@ -20,3 +20,4 @@
#include "BeastConfig.h"
#include "impl/RecursiveMutex.cpp"
+#include "impl/WaitableEvent.cpp"
diff --git a/modules/beast_core/threads/WaitableEvent.h b/beast/thread/WaitableEvent.h
similarity index 83%
rename from modules/beast_core/threads/WaitableEvent.h
rename to beast/thread/WaitableEvent.h
index 8cbb68c840..e4f4191046 100644
--- a/modules/beast_core/threads/WaitableEvent.h
+++ b/beast/thread/WaitableEvent.h
@@ -24,15 +24,23 @@
#ifndef BEAST_WAITABLEEVENT_H_INCLUDED
#define BEAST_WAITABLEEVENT_H_INCLUDED
-//==============================================================================
-/**
- Allows threads to wait for events triggered by other threads.
+#include "../Config.h"
+#include "../Uncopyable.h"
- A thread can call wait() on a WaitableObject, and this will suspend the
+#if ! BEAST_WINDOWS
+#include
+#endif
+
+namespace beast {
+
+/** Allows threads to wait for events triggered by other threads.
+ A thread can call wait() on a WaitableEvent, and this will suspend the
calling thread until another thread wakes it up by calling the signal()
method.
*/
-class BEAST_API WaitableEvent : LeakChecked , public Uncopyable
+class WaitableEvent
+ : public Uncopyable
+ //, LeakChecked // VFALCO TODO Move LeakChecked to beast/
{
public:
//==============================================================================
@@ -45,14 +53,14 @@ public:
@param initiallySignaled If this is true then the event will be signaled when
the constructor returns.
*/
- explicit WaitableEvent (bool manualReset = false, bool initiallySignaled = false) noexcept;
+ explicit WaitableEvent (bool manualReset = false, bool initiallySignaled = false);
/** Destructor.
If other threads are waiting on this object when it gets deleted, this
can cause nasty errors, so be careful!
*/
- ~WaitableEvent() noexcept;
+ ~WaitableEvent();
//==============================================================================
/** Suspends the calling thread until the event has been signalled.
@@ -69,7 +77,11 @@ public:
@returns true if the object has been signalled, false if the timeout expires first.
@see signal, reset
*/
- bool wait (int timeOutMilliseconds = -1) const noexcept;
+ /** @{ */
+ bool wait () const; // wait forever
+ // VFALCO TODO Change wait() to seconds instead of millis
+ bool wait (int timeOutMilliseconds) const; // DEPRECATED
+ /** @} */
//==============================================================================
/** Wakes up any threads that are currently waiting on this object.
@@ -87,26 +99,26 @@ public:
@see wait, reset
*/
- void signal() const noexcept;
+ void signal() const;
//==============================================================================
/** Resets the event to an unsignalled state.
If it's not already signalled, this does nothing.
*/
- void reset() const noexcept;
-
+ void reset() const;
private:
- //==============================================================================
- #if BEAST_WINDOWS
+#if BEAST_WINDOWS
void* handle;
- #else
+#else
mutable pthread_cond_t condition;
mutable pthread_mutex_t mutex;
- mutable bool triggered, manualReset;
- #endif
+ mutable bool triggered;
+ mutable bool manualReset;
+#endif
};
+}
-#endif // BEAST_WAITABLEEVENT_H_INCLUDED
+#endif
diff --git a/beast/thread/impl/WaitableEvent.cpp b/beast/thread/impl/WaitableEvent.cpp
new file mode 100644
index 0000000000..0a976c783a
--- /dev/null
+++ b/beast/thread/impl/WaitableEvent.cpp
@@ -0,0 +1,163 @@
+//------------------------------------------------------------------------------
+/*
+ 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 "../WaitableEvent.h"
+
+#if BEAST_WINDOWS
+
+#include
+
+namespace beast {
+
+WaitableEvent::WaitableEvent (const bool manualReset, bool initiallySignaled)
+ : handle (CreateEvent (0, manualReset ? TRUE : FALSE, initiallySignaled ? TRUE : FALSE, 0))
+{
+}
+
+WaitableEvent::~WaitableEvent()
+{
+ CloseHandle (handle);
+}
+
+void WaitableEvent::signal() const
+{
+ SetEvent (handle);
+}
+
+void WaitableEvent::reset() const
+{
+ ResetEvent (handle);
+}
+
+bool WaitableEvent::wait () const
+{
+ return WaitForSingleObject (handle, INFINITE) == WAIT_OBJECT_0;
+}
+
+bool WaitableEvent::wait (const int timeOutMs) const
+{
+ if (timeOutMs >= 0)
+ return WaitForSingleObject (handle,
+ (DWORD) timeOutMs) == WAIT_OBJECT_0;
+ return wait ();
+}
+
+}
+
+#else
+
+namespace beast {
+
+WaitableEvent::WaitableEvent (const bool useManualReset, bool initiallySignaled)
+ : triggered (false), manualReset (useManualReset)
+{
+ pthread_cond_init (&condition, 0);
+
+ pthread_mutexattr_t atts;
+ pthread_mutexattr_init (&atts);
+ #if ! BEAST_ANDROID
+ pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT);
+ #endif
+ pthread_mutex_init (&mutex, &atts);
+
+ if (initiallySignaled)
+ signal ();
+}
+
+WaitableEvent::~WaitableEvent()
+{
+ pthread_cond_destroy (&condition);
+ pthread_mutex_destroy (&mutex);
+}
+
+bool WaitableEvent::wait () const
+{
+ return wait (-1);
+}
+
+bool WaitableEvent::wait (const int timeOutMillisecs) const
+{
+ pthread_mutex_lock (&mutex);
+
+ if (! triggered)
+ {
+ if (timeOutMillisecs < 0)
+ {
+ do
+ {
+ pthread_cond_wait (&condition, &mutex);
+ }
+ while (! triggered);
+ }
+ else
+ {
+ struct timeval now;
+ gettimeofday (&now, 0);
+
+ struct timespec time;
+ time.tv_sec = now.tv_sec + (timeOutMillisecs / 1000);
+ time.tv_nsec = (now.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000;
+
+ if (time.tv_nsec >= 1000000000)
+ {
+ time.tv_nsec -= 1000000000;
+ time.tv_sec++;
+ }
+
+ do
+ {
+ if (pthread_cond_timedwait (&condition, &mutex, &time) == ETIMEDOUT)
+ {
+ pthread_mutex_unlock (&mutex);
+ return false;
+ }
+ }
+ while (! triggered);
+ }
+ }
+
+ if (! manualReset)
+ triggered = false;
+
+ pthread_mutex_unlock (&mutex);
+ return true;
+}
+
+void WaitableEvent::signal() const
+{
+ pthread_mutex_lock (&mutex);
+ triggered = true;
+ pthread_cond_broadcast (&condition);
+ pthread_mutex_unlock (&mutex);
+}
+
+void WaitableEvent::reset() const
+{
+ pthread_mutex_lock (&mutex);
+ triggered = false;
+ pthread_mutex_unlock (&mutex);
+}
+
+}
+
+#endif
diff --git a/modules/beast_core/beast_core.h b/modules/beast_core/beast_core.h
index c43fdce66e..1ea063eb4e 100644
--- a/modules/beast_core/beast_core.h
+++ b/modules/beast_core/beast_core.h
@@ -148,7 +148,6 @@ class FileOutputStream;
#include "memory/MemoryAlignment.h"
#include "memory/CacheLine.h"
#include "threads/ReadWriteMutex.h"
-#include "threads/WaitableEvent.h"
#include "threads/Thread.h"
#include "threads/SpinLock.h"
#include "threads/ThreadLocalValue.h"
diff --git a/modules/beast_core/native/posix_SharedCode.h b/modules/beast_core/native/posix_SharedCode.h
index 6b9cb1672f..95e72f9c33 100644
--- a/modules/beast_core/native/posix_SharedCode.h
+++ b/modules/beast_core/native/posix_SharedCode.h
@@ -38,92 +38,6 @@ void CriticalSection::enter() const noexcept { pthread_mutex_lock (&mutex); }
bool CriticalSection::tryEnter() const noexcept { return pthread_mutex_trylock (&mutex) == 0; }
void CriticalSection::exit() const noexcept { pthread_mutex_unlock (&mutex); }
-//==============================================================================
-WaitableEvent::WaitableEvent (const bool useManualReset, bool initiallySignaled) noexcept
- : triggered (false), manualReset (useManualReset)
-{
- pthread_cond_init (&condition, 0);
-
- pthread_mutexattr_t atts;
- pthread_mutexattr_init (&atts);
- #if ! BEAST_ANDROID
- pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT);
- #endif
- pthread_mutex_init (&mutex, &atts);
-
- if (initiallySignaled)
- signal ();
-}
-
-WaitableEvent::~WaitableEvent() noexcept
-{
- pthread_cond_destroy (&condition);
- pthread_mutex_destroy (&mutex);
-}
-
-bool WaitableEvent::wait (const int timeOutMillisecs) const noexcept
-{
- pthread_mutex_lock (&mutex);
-
- if (! triggered)
- {
- if (timeOutMillisecs < 0)
- {
- do
- {
- pthread_cond_wait (&condition, &mutex);
- }
- while (! triggered);
- }
- else
- {
- struct timeval now;
- gettimeofday (&now, 0);
-
- struct timespec time;
- time.tv_sec = now.tv_sec + (timeOutMillisecs / 1000);
- time.tv_nsec = (now.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000;
-
- if (time.tv_nsec >= 1000000000)
- {
- time.tv_nsec -= 1000000000;
- time.tv_sec++;
- }
-
- do
- {
- if (pthread_cond_timedwait (&condition, &mutex, &time) == ETIMEDOUT)
- {
- pthread_mutex_unlock (&mutex);
- return false;
- }
- }
- while (! triggered);
- }
- }
-
- if (! manualReset)
- triggered = false;
-
- pthread_mutex_unlock (&mutex);
- return true;
-}
-
-void WaitableEvent::signal() const noexcept
-{
- pthread_mutex_lock (&mutex);
- triggered = true;
- pthread_cond_broadcast (&condition);
- pthread_mutex_unlock (&mutex);
-}
-
-void WaitableEvent::reset() const noexcept
-{
- pthread_mutex_lock (&mutex);
- triggered = false;
- pthread_mutex_unlock (&mutex);
-}
-
//==============================================================================
void BEAST_CALLTYPE Thread::sleep (int millisecs)
{
diff --git a/modules/beast_core/native/win32_Threads.cpp b/modules/beast_core/native/win32_Threads.cpp
index 3cbc3afee3..6c77427878 100644
--- a/modules/beast_core/native/win32_Threads.cpp
+++ b/modules/beast_core/native/win32_Threads.cpp
@@ -72,21 +72,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); }
-//==============================================================================
-
-WaitableEvent::WaitableEvent (const bool manualReset, bool initiallySignaled) noexcept
- : handle (CreateEvent (0, manualReset ? TRUE : FALSE, initiallySignaled ? TRUE : FALSE, 0)) {}
-
-WaitableEvent::~WaitableEvent() noexcept { CloseHandle (handle); }
-
-void WaitableEvent::signal() const noexcept { SetEvent (handle); }
-void WaitableEvent::reset() const noexcept { ResetEvent (handle); }
-
-bool WaitableEvent::wait (const int timeOutMs) const noexcept
-{
- return WaitForSingleObject (handle, (DWORD) timeOutMs) == WAIT_OBJECT_0;
-}
-
//==============================================================================
void BEAST_API beast_threadEntryPoint (void*);