diff --git a/Builds/VisualStudio2012/Beast.props b/Builds/VisualStudio2012/Beast.props
index ce63ed759..4e9ca3e39 100644
--- a/Builds/VisualStudio2012/Beast.props
+++ b/Builds/VisualStudio2012/Beast.props
@@ -6,6 +6,7 @@
Level4
+ _CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions)
diff --git a/Builds/VisualStudio2012/BeastConfig.h b/Builds/VisualStudio2012/BeastConfig.h
index 42cf4e65c..3a86bf553 100644
--- a/Builds/VisualStudio2012/BeastConfig.h
+++ b/Builds/VisualStudio2012/BeastConfig.h
@@ -20,6 +20,15 @@
#ifndef BEAST_BEASTCONFIG_H_INCLUDED
#define BEAST_BEASTCONFIG_H_INCLUDED
+/** Configuration file for Beast.
+
+ This sets various configurable options for Beast. In order to compile you
+ must place a copy of this file in a location where your build environment
+ can find it, and then customize its contents to suit your needs.
+
+ @file BeastConfig.h
+*/
+
//------------------------------------------------------------------------------
/** Config: BEAST_FORCE_DEBUG
@@ -94,15 +103,22 @@
//------------------------------------------------------------------------------
-// beast_basics flags
+/** Config: BEAST_BOOST_IS_AVAILABLE
+ This activates boost specific features and improvements.
+*/
#ifndef BEAST_BOOST_IS_AVAILABLE
#define BEAST_BOOST_IS_AVAILABLE 0
#endif
-// Choose one to override default for platform
-//#define BEAST_BIND_USES_STD 1
-//#define BEAST_BIND_USES_TR1 1
+/** Bind source configuration.
+
+ Set one of these to manually force a particular implementation of bind().
+ If nothing is chosen then beast will use whatever is appropriate for your
+ environment based on what is available.
+*/
+//#define BEAST_BIND_USES_STD 1
+//#define BEAST_BIND_USES_TR1 1
//#define BEAST_BIND_USES_BOOST 1
#ifndef BEAST_USE_LEAKCHECKED
diff --git a/modules/beast_basics/beast_basics.h b/modules/beast_basics/beast_basics.h
index 5ab2fb0b8..cfbfdfaa2 100644
--- a/modules/beast_basics/beast_basics.h
+++ b/modules/beast_basics/beast_basics.h
@@ -234,64 +234,8 @@ Some files contain portions of these external projects, licensed separately:
#include
#endif
-#ifdef _CRTDBG_MAP_ALLOC
-#error "MSVC C Runtime Debug Macros not supported"
-#endif
-
-// If the MSVC debug heap headers were included, disable
-// the macros during the juce include since they conflict.
-#ifdef _CRTDBG_MAP_ALLOC
-#include
-#include
-#include
-
-#pragma push_macro("calloc")
-#pragma push_macro("free")
-#pragma push_macro("malloc")
-#pragma push_macro("realloc")
-#pragma push_macro("_recalloc")
-#pragma push_macro("_aligned_free")
-#pragma push_macro("_aligned_malloc")
-#pragma push_macro("_aligned_offset_malloc")
-#pragma push_macro("_aligned_realloc")
-#pragma push_macro("_aligned_recalloc")
-#pragma push_macro("_aligned_offset_realloc")
-#pragma push_macro("_aligned_offset_recalloc")
-#pragma push_macro("_aligned_msize")
-
-#undef calloc
-#undef free
-#undef malloc
-#undef realloc
-#undef _recalloc
-#undef _aligned_free
-#undef _aligned_malloc
-#undef _aligned_offset_malloc
-#undef _aligned_realloc
-#undef _aligned_recalloc
-#undef _aligned_offset_realloc
-#undef _aligned_offset_recalloc
-#undef _aligned_msize
-#endif
-
#include "../beast_core/beast_core.h"
-#ifdef _CRTDBG_MAP_ALLOC
-#pragma pop_macro("_aligned_msize")
-#pragma pop_macro("_aligned_offset_recalloc")
-#pragma pop_macro("_aligned_offset_realloc")
-#pragma pop_macro("_aligned_recalloc")
-#pragma pop_macro("_aligned_realloc")
-#pragma pop_macro("_aligned_offset_malloc")
-#pragma pop_macro("_aligned_malloc")
-#pragma pop_macro("_aligned_free")
-#pragma pop_macro("_recalloc")
-#pragma pop_macro("realloc")
-#pragma pop_macro("malloc")
-#pragma pop_macro("free")
-#pragma pop_macro("calloc")
-#endif
-
/** The Beast namespace.
This namespace contains all Beast symbols.
diff --git a/modules/beast_basics/memory/beast_FifoFreeStore.h b/modules/beast_basics/memory/beast_FifoFreeStore.h
index fafa2eeb2..92c7cbe79 100644
--- a/modules/beast_basics/memory/beast_FifoFreeStore.h
+++ b/modules/beast_basics/memory/beast_FifoFreeStore.h
@@ -24,7 +24,7 @@
@ingroup beast_concurrent
*/
-#if BEAST_BOOST_IS_AVAILABLE
+#if 0//BEAST_BOOST_IS_AVAILABLE
typedef FifoFreeStoreWithTLS FifoFreeStoreType;
#else
typedef FifoFreeStoreWithoutTLS FifoFreeStoreType;
diff --git a/modules/beast_basics/threads/beast_ThreadWithCallQueue.h b/modules/beast_basics/threads/beast_ThreadWithCallQueue.h
index c5fb1f621..ef6f153b6 100644
--- a/modules/beast_basics/threads/beast_ThreadWithCallQueue.h
+++ b/modules/beast_basics/threads/beast_ThreadWithCallQueue.h
@@ -20,29 +20,28 @@
#ifndef BEAST_THREADWITHCALLQUEUE_BEASTHEADER
#define BEAST_THREADWITHCALLQUEUE_BEASTHEADER
-/*============================================================================*/
-/**
- An InterruptibleThread with a CallQueue.
+/** An InterruptibleThread with a CallQueue.
- This combines an InterruptibleThread with a CallQueue, allowing functors to
- be queued for asynchronous execution on the thread.
+ This combines an InterruptibleThread with a CallQueue, allowing functors to
+ be queued for asynchronous execution on the thread.
- The thread runs an optional user-defined idle function, which must regularly
- check for an interruption using the InterruptibleThread interface. When an
- interruption is signaled, the idle function returns and the CallQueue is
- synchronized. Then, the idle function is resumed.
+ The thread runs an optional user-defined idle function, which must regularly
+ check for an interruption using the InterruptibleThread interface. When an
+ interruption is signaled, the idle function returns and the CallQueue is
+ synchronized. Then, the idle function is resumed.
- When the ThreadWithCallQueue first starts up, an optional user-defined
- initialization function is executed on the thread. When the thread exits,
- a user-defined exit function may be executed on the thread.
+ When the ThreadWithCallQueue first starts up, an optional user-defined
+ initialization function is executed on the thread. When the thread exits,
+ a user-defined exit function may be executed on the thread.
- @see CallQueue
+ @see CallQueue
- @ingroup beast_concurrent
+ @ingroup beast_concurrent
*/
class BEAST_API ThreadWithCallQueue
: public CallQueue
, private InterruptibleThread::EntryPoint
+ , LeakChecked
{
public:
/** Entry points for a ThreadWithCallQueue.
diff --git a/modules/beast_core/beast_core.cpp b/modules/beast_core/beast_core.cpp
index f06429c24..be3907d17 100644
--- a/modules/beast_core/beast_core.cpp
+++ b/modules/beast_core/beast_core.cpp
@@ -102,8 +102,39 @@
#include
#endif
+//------------------------------------------------------------------------------
+
+// If the MSVC debug heap headers were included, disable
+// the macros during the juce include since they conflict.
+#ifdef _CRTDBG_MAP_ALLOC
+#pragma push_macro("calloc")
+#pragma push_macro("free")
+#pragma push_macro("malloc")
+#pragma push_macro("realloc")
+#pragma push_macro("_recalloc")
+#pragma push_macro("_aligned_free")
+#pragma push_macro("_aligned_malloc")
+#pragma push_macro("_aligned_offset_malloc")
+#pragma push_macro("_aligned_realloc")
+#pragma push_macro("_aligned_recalloc")
+#pragma push_macro("_aligned_offset_realloc")
+#pragma push_macro("_aligned_offset_recalloc")
+#pragma push_macro("_aligned_msize")
+#undef calloc
+#undef free
+#undef malloc
+#undef realloc
+#undef _recalloc
+#undef _aligned_free
+#undef _aligned_malloc
+#undef _aligned_offset_malloc
+#undef _aligned_realloc
+#undef _aligned_recalloc
+#undef _aligned_offset_realloc
+#undef _aligned_offset_recalloc
+#undef _aligned_msize
+#endif
-//==============================================================================
namespace beast
{
@@ -184,7 +215,6 @@ namespace beast
#include "zip/beast_GZIPCompressorOutputStream.cpp"
#include "zip/beast_ZipFile.cpp"
-//==============================================================================
#if BEAST_MAC || BEAST_IOS
#include "native/beast_osx_ObjCHelpers.h"
#endif
@@ -198,7 +228,6 @@ namespace beast
#include "native/beast_posix_NamedPipe.cpp"
#endif
-//==============================================================================
#if BEAST_MAC || BEAST_IOS
#include "native/beast_mac_Files.mm"
#include "native/beast_mac_Network.mm"
@@ -206,7 +235,6 @@ namespace beast
#include "native/beast_mac_SystemStats.mm"
#include "native/beast_mac_Threads.mm"
-//==============================================================================
#elif BEAST_WINDOWS
#include "native/beast_win32_ComSmartPtr.h"
#include "native/beast_win32_Files.cpp"
@@ -215,21 +243,18 @@ namespace beast
#include "native/beast_win32_SystemStats.cpp"
#include "native/beast_win32_Threads.cpp"
-//==============================================================================
#elif BEAST_LINUX
#include "native/beast_linux_Files.cpp"
#include "native/beast_linux_Network.cpp"
#include "native/beast_linux_SystemStats.cpp"
#include "native/beast_linux_Threads.cpp"
-//==============================================================================
#elif BEAST_BSD
#include "native/beast_bsd_Files.cpp"
#include "native/beast_bsd_Network.cpp"
#include "native/beast_bsd_SystemStats.cpp"
#include "native/beast_bsd_Threads.cpp"
-//==============================================================================
#elif BEAST_ANDROID
#include "native/beast_android_Files.cpp"
#include "native/beast_android_Misc.cpp"
@@ -260,4 +285,3 @@ boost::arg<9> _9;
}
}
#endif
-
diff --git a/modules/beast_core/beast_core.h b/modules/beast_core/beast_core.h
index 258bc116d..0d1d6e157 100644
--- a/modules/beast_core/beast_core.h
+++ b/modules/beast_core/beast_core.h
@@ -150,6 +150,8 @@ using namespace placeholders;
//------------------------------------------------------------------------------
+#include "system/beast_StandardHeader.h"
+
#if BEAST_MSVC
# pragma warning (disable: 4251) // (DLL build warning, must be disabled before pushing the warning state)
# pragma warning (push)
@@ -159,7 +161,36 @@ using namespace placeholders;
# endif
#endif
-#include "system/beast_StandardHeader.h"
+// If the MSVC debug heap headers were included, disable
+// the macros during the juce include since they conflict.
+#ifdef _CRTDBG_MAP_ALLOC
+#pragma push_macro("calloc")
+#pragma push_macro("free")
+#pragma push_macro("malloc")
+#pragma push_macro("realloc")
+#pragma push_macro("_recalloc")
+#pragma push_macro("_aligned_free")
+#pragma push_macro("_aligned_malloc")
+#pragma push_macro("_aligned_offset_malloc")
+#pragma push_macro("_aligned_realloc")
+#pragma push_macro("_aligned_recalloc")
+#pragma push_macro("_aligned_offset_realloc")
+#pragma push_macro("_aligned_offset_recalloc")
+#pragma push_macro("_aligned_msize")
+#undef calloc
+#undef free
+#undef malloc
+#undef realloc
+#undef _recalloc
+#undef _aligned_free
+#undef _aligned_malloc
+#undef _aligned_offset_malloc
+#undef _aligned_realloc
+#undef _aligned_recalloc
+#undef _aligned_offset_realloc
+#undef _aligned_offset_recalloc
+#undef _aligned_msize
+#endif
namespace beast
{
@@ -291,8 +322,26 @@ namespace beast
}
-#if BEAST_MSVC
-# pragma warning (pop)
+#ifdef _CRTDBG_MAP_ALLOC
+#pragma pop_macro("_aligned_msize")
+#pragma pop_macro("_aligned_offset_recalloc")
+#pragma pop_macro("_aligned_offset_realloc")
+#pragma pop_macro("_aligned_recalloc")
+#pragma pop_macro("_aligned_realloc")
+#pragma pop_macro("_aligned_offset_malloc")
+#pragma pop_macro("_aligned_malloc")
+#pragma pop_macro("_aligned_free")
+#pragma pop_macro("_recalloc")
+#pragma pop_macro("realloc")
+#pragma pop_macro("malloc")
+#pragma pop_macro("free")
+#pragma pop_macro("calloc")
#endif
+#if BEAST_MSVC
+#pragma warning (pop)
+#endif
+
+//------------------------------------------------------------------------------
+
#endif
diff --git a/modules/beast_core/diagnostic/beast_Debug.cpp b/modules/beast_core/diagnostic/beast_Debug.cpp
index 9cf37f37b..d8e1245d4 100644
--- a/modules/beast_core/diagnostic/beast_Debug.cpp
+++ b/modules/beast_core/diagnostic/beast_Debug.cpp
@@ -20,35 +20,23 @@
namespace Debug
{
-//------------------------------------------------------------------------------
-
-bool isDebuggerAttached ()
-{
- return beast_isRunningUnderDebugger ();
-}
-
-//------------------------------------------------------------------------------
-
-#if BEAST_DEBUG && defined (beast_breakDebugger)
void breakPoint ()
{
- if (isDebuggerAttached ())
+#if BEAST_DEBUG
+ if (beast_isRunningUnderDebugger ())
beast_breakDebugger;
-}
#else
-void breakPoint ()
-{
- bassertfalse
-}
+ bassertfalse;
#endif
+}
-//----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
#if BEAST_MSVC && defined (_DEBUG)
-void setHeapAlwaysCheck (bool bAlwaysCheck)
+void setAlwaysCheckHeap (bool bAlwaysCheck)
{
int flags = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
@@ -78,14 +66,21 @@ void setHeapReportLeaks (bool bReportLeaks)
_CrtSetDbgFlag (flags);
}
+void reportLeaks ()
+{
+ _CrtDumpMemoryLeaks ();
+}
+
void checkHeap ()
{
_CrtCheckMemory ();
}
+//------------------------------------------------------------------------------
+
#else
-void setHeapAlwaysCheck (bool)
+void setAlwaysCheckHeap (bool)
{
}
@@ -97,6 +92,10 @@ void setHeapReportLeaks (bool)
{
}
+void reportLeaks ()
+{
+}
+
void checkHeap ()
{
}
diff --git a/modules/beast_core/diagnostic/beast_Debug.h b/modules/beast_core/diagnostic/beast_Debug.h
index 5382e37e3..c6013d46c 100644
--- a/modules/beast_core/diagnostic/beast_Debug.h
+++ b/modules/beast_core/diagnostic/beast_Debug.h
@@ -17,18 +17,18 @@
*/
//==============================================================================
-#ifndef BEAST_DEBUG_BEASTHEADER
-#define BEAST_DEBUG_BEASTHEADER
+#ifndef BEAST_DEBUG_H_INCLUDED
+#define BEAST_DEBUG_H_INCLUDED
// Auxiliary outines for debugging
namespace Debug
{
-// Returns true if a debugger is attached, for any build.
-extern bool isDebuggerAttached ();
+/** Break to debugger if a debugger is attached to a debug build.
-// Breaks to the debugger if a debugger is attached.
+ Does nothing if no debugger is attached, or the build is not a debug build.
+*/
extern void breakPoint ();
// VFALCO NOTE IS THIS REALLY THE RIGHT PLACE FOR THESE??
@@ -46,9 +46,34 @@ String stringToCommandLine (const String& s);
// that can contain newlines and double quotes.
String commandLineToString (const String& commandLine);
-extern void setHeapAlwaysCheck (bool bAlwaysCheck);
+//
+// These control the MSVC C Runtime Debug heap.
+//
+// The calls currently do nothing on other platforms.
+//
+
+/** Calls checkHeap() at every allocation and deallocation.
+*/
+extern void setAlwaysCheckHeap (bool bAlwaysCheck);
+
+/** Keep freed memory blocks in the heap's linked list, assign them the
+ _FREE_BLOCK type, and fill them with the byte value 0xDD.
+*/
extern void setHeapDelayedFree (bool bDelayedFree);
+
+/** Perform automatic leak checking at program exit through a call to
+ dumpMemoryLeaks() and generate an error report if the application
+ failed to free all the memory it allocated.
+*/
extern void setHeapReportLeaks (bool bReportLeaks);
+
+/** Report all memory blocks which have not been freed.
+*/
+extern void reportLeaks ();
+
+/** Confirms the integrity of the memory blocks allocated in the
+ debug heap (debug version only.
+*/
extern void checkHeap ();
}
diff --git a/modules/beast_core/diagnostic/beast_LeakChecked.cpp b/modules/beast_core/diagnostic/beast_LeakChecked.cpp
index 0cf686ec7..0688c3cd2 100644
--- a/modules/beast_core/diagnostic/beast_LeakChecked.cpp
+++ b/modules/beast_core/diagnostic/beast_LeakChecked.cpp
@@ -76,7 +76,7 @@ void LeakCheckedBase::CounterBase::detectLeaks ()
if (count > 0)
{
- bassertfalse;
+ //bassertfalse;
DBG ("[LEAK] " << count << " of " << getClassName ());
}
}
diff --git a/modules/beast_core/diagnostic/beast_Throw.h b/modules/beast_core/diagnostic/beast_Throw.h
index e5b3f9457..a488193fe 100644
--- a/modules/beast_core/diagnostic/beast_Throw.h
+++ b/modules/beast_core/diagnostic/beast_Throw.h
@@ -17,10 +17,8 @@
*/
//==============================================================================
-#ifndef BEAST_THROW_BEASTHEADER
-#define BEAST_THROW_BEASTHEADER
-
-#include "beast_Debug.h"
+#ifndef BEAST_THROW_H_INCLUDED
+#define BEAST_THROW_H_INCLUDED
/** Throw an exception, with a debugger hook.
@@ -30,7 +28,6 @@
template
inline void Throw (Exception const& e)
{
- // VFALCO TODO Replace with straight JUCE equivalent
Debug::breakPoint ();
throw e;
diff --git a/modules/beast_core/memory/beast_LeakedObjectDetector.h b/modules/beast_core/memory/beast_LeakedObjectDetector.h
index eaa01b15d..cc45e61dc 100644
--- a/modules/beast_core/memory/beast_LeakedObjectDetector.h
+++ b/modules/beast_core/memory/beast_LeakedObjectDetector.h
@@ -90,7 +90,7 @@ private:
your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays,
ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs!
*/
- bassertfalse;
+ //bassertfalse;
}
}
diff --git a/modules/beast_core/native/beast_win32_Misc.cpp b/modules/beast_core/native/beast_win32_Misc.cpp
new file mode 100644
index 000000000..4a2f785a2
--- /dev/null
+++ b/modules/beast_core/native/beast_win32_Misc.cpp
@@ -0,0 +1,648 @@
+//------------------------------------------------------------------------------
+/*
+ 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.
+*/
+//==============================================================================
+
+HWND beast_messageWindowHandle = 0; // (this is used by other parts of the codebase)
+
+//==============================================================================
+#if ! BEAST_USE_INTRINSICS
+// In newer compilers, the inline versions of these are used (in beast_Atomic.h), but in
+// older ones we have to actually call the ops as win32 functions..
+long beast_InterlockedExchange (volatile long* a, long b) noexcept { return InterlockedExchange (a, b); }
+long beast_InterlockedIncrement (volatile long* a) noexcept { return InterlockedIncrement (a); }
+long beast_InterlockedDecrement (volatile long* a) noexcept { return InterlockedDecrement (a); }
+long beast_InterlockedExchangeAdd (volatile long* a, long b) noexcept { return InterlockedExchangeAdd (a, b); }
+long beast_InterlockedCompareExchange (volatile long* a, long b, long c) noexcept { return InterlockedCompareExchange (a, b, c); }
+
+__int64 beast_InterlockedCompareExchange64 (volatile __int64* value, __int64 newValue, __int64 valueToCompare) noexcept
+{
+ bassertfalse; // This operation isn't available in old MS compiler versions!
+
+ __int64 oldValue = *value;
+ if (oldValue == valueToCompare)
+ *value = newValue;
+
+ return oldValue;
+}
+
+#endif
+
+//==============================================================================
+CriticalSection::CriticalSection() noexcept
+{
+ // (just to check the MS haven't changed this structure and broken things...)
+ #if BEAST_VC7_OR_EARLIER
+ static_bassert (sizeof (CRITICAL_SECTION) <= 24);
+ #else
+ static_bassert (sizeof (CRITICAL_SECTION) <= sizeof (internal));
+ #endif
+
+ InitializeCriticalSection ((CRITICAL_SECTION*) internal);
+}
+
+CriticalSection::~CriticalSection() noexcept
+{
+ DeleteCriticalSection ((CRITICAL_SECTION*) internal);
+}
+
+void CriticalSection::enter() const noexcept
+{
+ EnterCriticalSection ((CRITICAL_SECTION*) internal);
+}
+
+bool CriticalSection::tryEnter() const noexcept
+{
+ return TryEnterCriticalSection ((CRITICAL_SECTION*) internal) != FALSE;
+}
+
+void CriticalSection::exit() const noexcept
+{
+ LeaveCriticalSection ((CRITICAL_SECTION*) internal);
+}
+
+//==============================================================================
+WaitableEvent::WaitableEvent (const bool manualReset) noexcept
+ : internal (CreateEvent (0, manualReset ? TRUE : FALSE, FALSE, 0))
+{
+}
+
+WaitableEvent::~WaitableEvent() noexcept
+{
+ CloseHandle (internal);
+}
+
+bool WaitableEvent::wait (const int timeOutMillisecs) const noexcept
+{
+ return WaitForSingleObject (internal, (DWORD) timeOutMillisecs) == WAIT_OBJECT_0;
+}
+
+void WaitableEvent::signal() const noexcept
+{
+ SetEvent (internal);
+}
+
+void WaitableEvent::reset() const noexcept
+{
+ ResetEvent (internal);
+}
+
+//==============================================================================
+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;
+
+// called by WindowDriver because Windows does weird things to process priority
+// when you swap apps, and this forces an update when the app is brought to the front.
+void beast_repeatLastProcessPriority()
+{
+ if (lastProcessPriority >= 0) // (avoid changing this if it's not been explicitly set by the app..)
+ {
+ DWORD p;
+
+ switch (lastProcessPriority)
+ {
+ case Process::LowPriority: p = IDLE_PRIORITY_CLASS; break;
+ case Process::NormalPriority: p = NORMAL_PRIORITY_CLASS; break;
+ case Process::HighPriority: p = HIGH_PRIORITY_CLASS; break;
+ case Process::RealtimePriority: p = REALTIME_PRIORITY_CLASS; break;
+ default: bassertfalse; return; // bad priority value
+ }
+
+ SetPriorityClass (GetCurrentProcess(), p);
+ }
+}
+
+void Process::setPriority (ProcessPriority prior)
+{
+ if (lastProcessPriority != (int) prior)
+ {
+ lastProcessPriority = (int) prior;
+ beast_repeatLastProcessPriority();
+ }
+}
+
+BEAST_API bool BEAST_CALLTYPE beast_isRunningUnderDebugger()
+{
+ return IsDebuggerPresent() != FALSE;
+}
+
+bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
+{
+ return beast_isRunningUnderDebugger();
+}
+
+BEAST_API void BEAST_CALLTYPE Process::breakPoint ()
+{
+#if BEAST_DEBUG
+ if (beast_isRunningUnderDebugger ())
+ beast_breakDebugger;
+
+#else
+ bassertfalse;
+
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+static void* currentModuleHandle = nullptr;
+
+void* Process::getCurrentModuleInstanceHandle() noexcept
+{
+ if (currentModuleHandle == nullptr)
+ currentModuleHandle = GetModuleHandleA (nullptr);
+
+ return currentModuleHandle;
+}
+
+void Process::setCurrentModuleInstanceHandle (void* const newHandle) noexcept
+{
+ currentModuleHandle = newHandle;
+}
+
+void Process::raisePrivilege()
+{
+ bassertfalse; // xxx not implemented
+}
+
+void Process::lowerPrivilege()
+{
+ bassertfalse; // xxx not implemented
+}
+
+void Process::terminate()
+{
+ #if BEAST_MSVC && BEAST_CHECK_MEMORY_LEAKS
+ _CrtDumpMemoryLeaks();
+ #endif
+
+ // bullet in the head in case there's a problem shutting down..
+ ExitProcess (0);
+}
+
+bool beast_isRunningInWine()
+{
+ HMODULE ntdll = GetModuleHandleA ("ntdll");
+ return ntdll != 0 && GetProcAddress (ntdll, "wine_get_version") != nullptr;
+}
+
+//==============================================================================
+bool DynamicLibrary::open (const String& name)
+{
+ close();
+
+ BEAST_TRY
+ {
+ handle = LoadLibrary (name.toWideCharPointer());
+ }
+ BEAST_CATCH_ALL
+
+ return handle != nullptr;
+}
+
+void DynamicLibrary::close()
+{
+ BEAST_TRY
+ {
+ if (handle != nullptr)
+ {
+ FreeLibrary ((HMODULE) handle);
+ handle = nullptr;
+ }
+ }
+ BEAST_CATCH_ALL
+}
+
+void* DynamicLibrary::getFunction (const String& functionName) noexcept
+{
+ return handle != nullptr ? (void*) GetProcAddress ((HMODULE) handle, functionName.toUTF8()) // (void* cast is required for mingw)
+ : nullptr;
+}
+
+
+//==============================================================================
+class InterProcessLock::Pimpl
+{
+public:
+ Pimpl (String name, const int timeOutMillisecs)
+ : handle (0), refCount (1)
+ {
+ name = name.replaceCharacter ('\\', '/');
+ handle = CreateMutexW (0, TRUE, ("Global\\" + name).toWideCharPointer());
+
+ // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to
+ // a local one. (A local one also sometimes fails on other machines so neither type appears to be
+ // universally reliable)
+ if (handle == 0)
+ handle = CreateMutexW (0, TRUE, ("Local\\" + name).toWideCharPointer());
+
+ if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ if (timeOutMillisecs == 0)
+ {
+ close();
+ return;
+ }
+
+ switch (WaitForSingleObject (handle, timeOutMillisecs < 0 ? INFINITE : timeOutMillisecs))
+ {
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED:
+ break;
+
+ case WAIT_TIMEOUT:
+ default:
+ close();
+ break;
+ }
+ }
+ }
+
+ ~Pimpl()
+ {
+ close();
+ }
+
+ void close()
+ {
+ if (handle != 0)
+ {
+ ReleaseMutex (handle);
+ CloseHandle (handle);
+ handle = 0;
+ }
+ }
+
+ HANDLE handle;
+ int refCount;
+};
+
+InterProcessLock::InterProcessLock (const String& name_)
+ : name (name_)
+{
+}
+
+InterProcessLock::~InterProcessLock()
+{
+}
+
+bool InterProcessLock::enter (const int timeOutMillisecs)
+{
+ const ScopedLock sl (lock);
+
+ if (pimpl == nullptr)
+ {
+ pimpl = new Pimpl (name, timeOutMillisecs);
+
+ if (pimpl->handle == 0)
+ pimpl = nullptr;
+ }
+ else
+ {
+ pimpl->refCount++;
+ }
+
+ return pimpl != nullptr;
+}
+
+void InterProcessLock::exit()
+{
+ const ScopedLock sl (lock);
+
+ // Trying to release the lock too many times!
+ bassert (pimpl != nullptr);
+
+ if (pimpl != nullptr && --(pimpl->refCount) == 0)
+ pimpl = nullptr;
+}
+
+//==============================================================================
+class ChildProcess::ActiveProcess
+{
+public:
+ ActiveProcess (const String& command)
+ : ok (false), readPipe (0), writePipe (0)
+ {
+ SECURITY_ATTRIBUTES securityAtts = { 0 };
+ securityAtts.nLength = sizeof (securityAtts);
+ securityAtts.bInheritHandle = TRUE;
+
+ if (CreatePipe (&readPipe, &writePipe, &securityAtts, 0)
+ && SetHandleInformation (readPipe, HANDLE_FLAG_INHERIT, 0))
+ {
+ STARTUPINFOW startupInfo = { 0 };
+ startupInfo.cb = sizeof (startupInfo);
+ startupInfo.hStdError = writePipe;
+ startupInfo.hStdOutput = writePipe;
+ startupInfo.dwFlags = STARTF_USESTDHANDLES;
+
+ ok = CreateProcess (nullptr, const_cast (command.toWideCharPointer()),
+ nullptr, nullptr, TRUE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
+ nullptr, nullptr, &startupInfo, &processInfo) != FALSE;
+ }
+ }
+
+ ~ActiveProcess()
+ {
+ if (ok)
+ {
+ CloseHandle (processInfo.hThread);
+ CloseHandle (processInfo.hProcess);
+ }
+
+ if (readPipe != 0)
+ CloseHandle (readPipe);
+
+ if (writePipe != 0)
+ CloseHandle (writePipe);
+ }
+
+ bool isRunning() const
+ {
+ return WaitForSingleObject (processInfo.hProcess, 0) != WAIT_OBJECT_0;
+ }
+
+ int read (void* dest, int numNeeded) const
+ {
+ int total = 0;
+
+ while (ok && numNeeded > 0)
+ {
+ DWORD available = 0;
+
+ if (! PeekNamedPipe ((HANDLE) readPipe, nullptr, 0, nullptr, &available, nullptr))
+ break;
+
+ const int numToDo = bmin ((int) available, numNeeded);
+
+ if (available == 0)
+ {
+ if (! isRunning())
+ break;
+
+ Thread::yield();
+ }
+ else
+ {
+ DWORD numRead = 0;
+ if (! ReadFile ((HANDLE) readPipe, dest, numToDo, &numRead, nullptr))
+ break;
+
+ total += numRead;
+ dest = addBytesToPointer (dest, numRead);
+ numNeeded -= numRead;
+ }
+ }
+
+ return total;
+ }
+
+ bool killProcess() const
+ {
+ return TerminateProcess (processInfo.hProcess, 0) != FALSE;
+ }
+
+ bool ok;
+
+private:
+ HANDLE readPipe, writePipe;
+ PROCESS_INFORMATION processInfo;
+
+ BEAST_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveProcess)
+};
+
+bool ChildProcess::start (const String& command)
+{
+ activeProcess = new ActiveProcess (command);
+
+ if (! activeProcess->ok)
+ activeProcess = nullptr;
+
+ return activeProcess != nullptr;
+}
+
+bool ChildProcess::start (const StringArray& args)
+{
+ return start (args.joinIntoString (" "));
+}
+
+bool ChildProcess::isRunning() const
+{
+ return activeProcess != nullptr && activeProcess->isRunning();
+}
+
+int ChildProcess::readProcessOutput (void* dest, int numBytes)
+{
+ return activeProcess != nullptr ? activeProcess->read (dest, numBytes) : 0;
+}
+
+bool ChildProcess::kill()
+{
+ return activeProcess == nullptr || activeProcess->killProcess();
+}
+
+//==============================================================================
+struct HighResolutionTimer::Pimpl
+{
+ Pimpl (HighResolutionTimer& t) noexcept : owner (t), periodMs (0)
+ {
+ }
+
+ ~Pimpl()
+ {
+ bassert (periodMs == 0);
+ }
+
+ void start (int newPeriod)
+ {
+ if (newPeriod != periodMs)
+ {
+ stop();
+ periodMs = newPeriod;
+
+ TIMECAPS tc;
+ if (timeGetDevCaps (&tc, sizeof (tc)) == TIMERR_NOERROR)
+ {
+ const int actualPeriod = blimit ((int) tc.wPeriodMin, (int) tc.wPeriodMax, newPeriod);
+
+ timerID = timeSetEvent (actualPeriod, tc.wPeriodMin, callbackFunction, (DWORD_PTR) this,
+ TIME_PERIODIC | TIME_CALLBACK_FUNCTION | 0x100 /*TIME_KILL_SYNCHRONOUS*/);
+ }
+ }
+ }
+
+ void stop()
+ {
+ periodMs = 0;
+ timeKillEvent (timerID);
+ }
+
+ HighResolutionTimer& owner;
+ int periodMs;
+
+private:
+ unsigned int timerID;
+
+ static void __stdcall callbackFunction (UINT, UINT, DWORD_PTR userInfo, DWORD_PTR, DWORD_PTR)
+ {
+ if (Pimpl* const timer = reinterpret_cast (userInfo))
+ if (timer->periodMs != 0)
+ timer->owner.hiResTimerCallback();
+ }
+
+ BEAST_DECLARE_NON_COPYABLE (Pimpl)
+};
diff --git a/modules/beast_core/native/beast_win32_Threads.cpp b/modules/beast_core/native/beast_win32_Threads.cpp
index 2274bec65..937069576 100644
--- a/modules/beast_core/native/beast_win32_Threads.cpp
+++ b/modules/beast_core/native/beast_win32_Threads.cpp
@@ -285,6 +285,8 @@ bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
return beast_isRunningUnderDebugger();
}
+//------------------------------------------------------------------------------
+
static void* currentModuleHandle = nullptr;
void* Process::getCurrentModuleInstanceHandle() noexcept
diff --git a/modules/beast_core/system/beast_PlatformDefs.h b/modules/beast_core/system/beast_PlatformDefs.h
index 59b93ba3c..63323de40 100644
--- a/modules/beast_core/system/beast_PlatformDefs.h
+++ b/modules/beast_core/system/beast_PlatformDefs.h
@@ -24,118 +24,113 @@
#ifndef BEAST_PLATFORMDEFS_BEASTHEADER
#define BEAST_PLATFORMDEFS_BEASTHEADER
-//==============================================================================
-/* This file defines miscellaneous macros for debugging, assertions, etc.
-*/
+// This file defines miscellaneous macros for debugging, assertions, etc.
-//==============================================================================
#ifdef BEAST_FORCE_DEBUG
- #undef BEAST_DEBUG
-
- #if BEAST_FORCE_DEBUG
- #define BEAST_DEBUG 1
- #endif
+# undef BEAST_DEBUG
+# if BEAST_FORCE_DEBUG
+# define BEAST_DEBUG 1
+# endif
#endif
-/** This macro defines the C calling convention used as the standard for Beast calls. */
+/** This macro defines the C calling convention used as the standard for Beast calls.
+*/
#if BEAST_MSVC
- #define BEAST_CALLTYPE __stdcall
- #define BEAST_CDECL __cdecl
+# define BEAST_CALLTYPE __stdcall
+# define BEAST_CDECL __cdecl
#else
- #define BEAST_CALLTYPE
- #define BEAST_CDECL
+# define BEAST_CALLTYPE
+# define BEAST_CDECL
#endif
-//==============================================================================
// Debugging and assertion macros
#if BEAST_LOG_ASSERTIONS || BEAST_DEBUG
- #define beast_LogCurrentAssertion beast::logAssertion (__FILE__, __LINE__);
+#define beast_LogCurrentAssertion beast::logAssertion (__FILE__, __LINE__);
#else
- #define beast_LogCurrentAssertion
+#define beast_LogCurrentAssertion
#endif
-//==============================================================================
#if BEAST_IOS || BEAST_LINUX || BEAST_ANDROID || BEAST_PPC
- /** This will try to break into the debugger if the app is currently being debugged.
- If called by an app that's not being debugged, the behaiour isn't defined - it may crash or not, depending
- on the platform.
- @see bassert()
- */
- #define beast_breakDebugger { ::kill (0, SIGTRAP); }
+/** This will try to break into the debugger if the app is currently being debugged.
+ If called by an app that's not being debugged, the behaiour isn't defined - it may crash or not, depending
+ on the platform.
+ @see bassert()
+*/
+# define beast_breakDebugger { ::kill (0, SIGTRAP); }
#elif BEAST_USE_INTRINSICS
- #ifndef __INTEL_COMPILER
- #pragma intrinsic (__debugbreak)
- #endif
- #define beast_breakDebugger { __debugbreak(); }
+# ifndef __INTEL_COMPILER
+# pragma intrinsic (__debugbreak)
+# endif
+# define beast_breakDebugger { __debugbreak(); }
#elif BEAST_GCC || BEAST_MAC
- #if BEAST_NO_INLINE_ASM
- #define beast_breakDebugger { }
- #else
- #define beast_breakDebugger { asm ("int $3"); }
- #endif
+# if BEAST_NO_INLINE_ASM
+# define beast_breakDebugger { }
+# else
+# define beast_breakDebugger { asm ("int $3"); }
+# endif
#else
- #define beast_breakDebugger { __asm int 3 }
+# define beast_breakDebugger { __asm int 3 }
#endif
#if BEAST_CLANG && defined (__has_feature) && ! defined (BEAST_ANALYZER_NORETURN)
- #if __has_feature (attribute_analyzer_noreturn)
- inline void __attribute__((analyzer_noreturn)) beast_assert_noreturn() {}
- #define BEAST_ANALYZER_NORETURN beast_assert_noreturn();
- #endif
+# if __has_feature (attribute_analyzer_noreturn)
+ inline void __attribute__((analyzer_noreturn)) beast_assert_noreturn() {}
+# define BEAST_ANALYZER_NORETURN beast_assert_noreturn();
+# endif
#endif
#ifndef BEAST_ANALYZER_NORETURN
- #define BEAST_ANALYZER_NORETURN
+#define BEAST_ANALYZER_NORETURN
#endif
+//------------------------------------------------------------------------------
-//==============================================================================
#if BEAST_DEBUG || DOXYGEN
- /** Writes a string to the standard error stream.
- This is only compiled in a debug build.
- @see Logger::outputDebugString
- */
- #define DBG(dbgtext) { beast::String tempDbgBuf; tempDbgBuf << dbgtext; beast::Logger::outputDebugString (tempDbgBuf); }
- //==============================================================================
- /** This will always cause an assertion failure.
- It is only compiled in a debug build, (unless BEAST_LOG_ASSERTIONS is enabled for your build).
- @see bassert
- */
- #define bassertfalse { beast_LogCurrentAssertion; if (beast::beast_isRunningUnderDebugger()) beast_breakDebugger; BEAST_ANALYZER_NORETURN }
+/** Writes a string to the standard error stream.
+ This is only compiled in a debug build.
+ @see Logger::outputDebugString
+*/
+#define DBG(dbgtext) { beast::String tempDbgBuf; tempDbgBuf << dbgtext; beast::Logger::outputDebugString (tempDbgBuf); }
- //==============================================================================
- /** Platform-independent assertion macro.
+/** This will always cause an assertion failure.
+ It is only compiled in a debug build, (unless BEAST_LOG_ASSERTIONS is enabled for your build).
+ @see bassert
+*/
+#define bassertfalse { beast_LogCurrentAssertion; if (beast::beast_isRunningUnderDebugger()) beast_breakDebugger; BEAST_ANALYZER_NORETURN }
- This macro gets turned into a no-op when you're building with debugging turned off, so be
- careful that the expression you pass to it doesn't perform any actions that are vital for the
- correct behaviour of your program!
- @see bassertfalse
+/** Platform-independent assertion macro.
+
+ This macro gets turned into a no-op when you're building with debugging turned off, so be
+ careful that the expression you pass to it doesn't perform any actions that are vital for the
+ correct behaviour of your program!
+ @see bassertfalse
*/
- #define bassert(expression) { if (! (expression)) bassertfalse; }
+#define bassert(expression) { if (! (expression)) bassertfalse; }
#else
- //==============================================================================
- // If debugging is disabled, these dummy debug and assertion macros are used..
- #define DBG(dbgtext)
- #define bassertfalse { beast_LogCurrentAssertion }
+// If debugging is disabled, these dummy debug and assertion macros are used..
- #if BEAST_LOG_ASSERTIONS
- #define bassert(expression) { if (! (expression)) bassertfalse; }
- #else
- #define bassert(a) {}
- #endif
+#define DBG(dbgtext)
+#define bassertfalse { beast_LogCurrentAssertion }
+
+# if BEAST_LOG_ASSERTIONS
+# define bassert(expression) { if (! (expression)) bassertfalse; }
+# else
+# define bassert(a) {}
+# endif
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
#ifndef DOXYGEN
namespace beast
{
- template struct BeastStaticAssert;
- template <> struct BeastStaticAssert { static void dummy() {} };
+template struct BeastStaticAssert;
+template <> struct BeastStaticAssert { static void dummy() {} };
}
#endif
@@ -189,8 +184,8 @@ namespace beast
static void* operator new (size_t); \
static void operator delete (void*);
+//------------------------------------------------------------------------------
-//==============================================================================
#if ! DOXYGEN
#define BEAST_JOIN_MACRO_HELPER(a, b) a ## b
#define BEAST_STRINGIFY_MACRO_HELPER(a) #a
@@ -206,158 +201,140 @@ namespace beast
*/
#define BEAST_STRINGIFY(item) BEAST_STRINGIFY_MACRO_HELPER (item)
+//------------------------------------------------------------------------------
-//==============================================================================
#if BEAST_CATCH_UNHANDLED_EXCEPTIONS
-
- #define BEAST_TRY try
-
- #define BEAST_CATCH_ALL catch (...) {}
- #define BEAST_CATCH_ALL_ASSERT catch (...) { bassertfalse; }
-
- #if ! BEAST_MODULE_AVAILABLE_beast_gui_basics
- #define BEAST_CATCH_EXCEPTION BEAST_CATCH_ALL
- #else
- /** Used in try-catch blocks, this macro will send exceptions to the BEASTApplication
- object so they can be logged by the application if it wants to.
- */
- #define BEAST_CATCH_EXCEPTION \
- catch (const std::exception& e) \
- { \
- beast::BEASTApplication::sendUnhandledException (&e, __FILE__, __LINE__); \
- } \
- catch (...) \
- { \
- beast::BEASTApplication::sendUnhandledException (nullptr, __FILE__, __LINE__); \
- }
- #endif
+# define BEAST_TRY try
+# define BEAST_CATCH_ALL catch (...) {}
+# define BEAST_CATCH_ALL_ASSERT catch (...) { bassertfalse; }
+# define BEAST_CATCH_EXCEPTION BEAST_CATCH_ALL
#else
-
- #define BEAST_TRY
- #define BEAST_CATCH_EXCEPTION
- #define BEAST_CATCH_ALL
- #define BEAST_CATCH_ALL_ASSERT
+# define BEAST_TRY
+# define BEAST_CATCH_EXCEPTION
+# define BEAST_CATCH_ALL
+# define BEAST_CATCH_ALL_ASSERT
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
#if BEAST_DEBUG || DOXYGEN
- /** A platform-independent way of forcing an inline function.
- Use the syntax: @code
- forcedinline void myfunction (int x)
- @endcode
- */
- #define forcedinline inline
+/** A platform-independent way of forcing an inline function.
+ Use the syntax: @code
+ forcedinline void myfunction (int x)
+ @endcode
+*/
+# define forcedinline inline
+#elif BEAST_MSVC
+# define forcedinline __forceinline
#else
- #if BEAST_MSVC
- #define forcedinline __forceinline
- #else
- #define forcedinline inline __attribute__((always_inline))
- #endif
+# define forcedinline inline __attribute__((always_inline))
#endif
#if BEAST_MSVC || DOXYGEN
- /** This can be placed before a stack or member variable declaration to tell the compiler
- to align it to the specified number of bytes. */
- #define BEAST_ALIGN(bytes) __declspec (align (bytes))
+/** This can be placed before a stack or member variable declaration to tell
+ the compiler to align it to the specified number of bytes.
+*/
+#define BEAST_ALIGN(bytes) __declspec (align (bytes))
#else
- #define BEAST_ALIGN(bytes) __attribute__ ((aligned (bytes)))
+#define BEAST_ALIGN(bytes) __attribute__ ((aligned (bytes)))
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
// Cross-compiler deprecation macros..
#if DOXYGEN || (BEAST_MSVC && ! BEAST_NO_DEPRECATION_WARNINGS)
- /** This can be used to wrap a function which has been deprecated. */
- #define BEAST_DEPRECATED(functionDef) __declspec(deprecated) functionDef
+/** This can be used to wrap a function which has been deprecated. */
+# define BEAST_DEPRECATED(functionDef) __declspec(deprecated) functionDef
#elif BEAST_GCC && ! BEAST_NO_DEPRECATION_WARNINGS
- #define BEAST_DEPRECATED(functionDef) functionDef __attribute__ ((deprecated))
+# define BEAST_DEPRECATED(functionDef) functionDef __attribute__ ((deprecated))
#else
- #define BEAST_DEPRECATED(functionDef) functionDef
+# define BEAST_DEPRECATED(functionDef) functionDef
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
#if BEAST_ANDROID && ! DOXYGEN
- #define BEAST_MODAL_LOOPS_PERMITTED 0
+# define BEAST_MODAL_LOOPS_PERMITTED 0
#elif ! defined (BEAST_MODAL_LOOPS_PERMITTED)
- /** Some operating environments don't provide a modal loop mechanism, so this flag can be
- used to disable any functions that try to run a modal loop. */
+ /** Some operating environments don't provide a modal loop mechanism, so this
+ flag can be used to disable any functions that try to run a modal loop.
+ */
#define BEAST_MODAL_LOOPS_PERMITTED 1
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
#if BEAST_GCC
- #define BEAST_PACKED __attribute__((packed))
+# define BEAST_PACKED __attribute__((packed))
#elif ! DOXYGEN
- #define BEAST_PACKED
+# define BEAST_PACKED
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
// Here, we'll check for C++11 compiler support, and if it's not available, define
// a few workarounds, so that we can still use some of the newer language features.
#if defined (__GXX_EXPERIMENTAL_CXX0X__) && defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
- #define BEAST_COMPILER_SUPPORTS_NOEXCEPT 1
- #define BEAST_COMPILER_SUPPORTS_NULLPTR 1
- #define BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
-
- #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && ! defined (BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL)
- #define BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1
- #endif
+# define BEAST_COMPILER_SUPPORTS_NOEXCEPT 1
+# define BEAST_COMPILER_SUPPORTS_NULLPTR 1
+# define BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && ! defined (BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL)
+# define BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1
+# endif
#endif
#if BEAST_CLANG && defined (__has_feature)
- #if __has_feature (cxx_nullptr)
- #define BEAST_COMPILER_SUPPORTS_NULLPTR 1
- #endif
-
- #if __has_feature (cxx_noexcept)
- #define BEAST_COMPILER_SUPPORTS_NOEXCEPT 1
- #endif
-
- #if __has_feature (cxx_rvalue_references)
- #define BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
- #endif
-
- #ifndef BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL
- #define BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1
- #endif
-
- #ifndef BEAST_COMPILER_SUPPORTS_ARC
- #define BEAST_COMPILER_SUPPORTS_ARC 1
- #endif
+# if __has_feature (cxx_nullptr)
+# define BEAST_COMPILER_SUPPORTS_NULLPTR 1
+# endif
+# if __has_feature (cxx_noexcept)
+# define BEAST_COMPILER_SUPPORTS_NOEXCEPT 1
+# endif
+# if __has_feature (cxx_rvalue_references)
+# define BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
+# endif
+# ifndef BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL
+# define BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1
+# endif
+# ifndef BEAST_COMPILER_SUPPORTS_ARC
+# define BEAST_COMPILER_SUPPORTS_ARC 1
+# endif
#endif
#if defined (_MSC_VER) && _MSC_VER >= 1600
- #define BEAST_COMPILER_SUPPORTS_NULLPTR 1
- #define BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
+# define BEAST_COMPILER_SUPPORTS_NULLPTR 1
+# define BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
#endif
#if defined (_MSC_VER) && _MSC_VER >= 1700
- #define BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1
+# define BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1
#endif
-//==============================================================================
+//------------------------------------------------------------------------------
+
// Declare some fake versions of nullptr and noexcept, for older compilers:
#if ! (DOXYGEN || BEAST_COMPILER_SUPPORTS_NOEXCEPT)
- #ifdef noexcept
- #undef noexcept
- #endif
- #define noexcept throw()
- #if defined (_MSC_VER) && _MSC_VER > 1600
- #define _ALLOW_KEYWORD_MACROS 1 // (to stop VC2012 complaining)
- #endif
+# ifdef noexcept
+# undef noexcept
+# endif
+# define noexcept throw()
+# if defined (_MSC_VER) && _MSC_VER > 1600
+# define _ALLOW_KEYWORD_MACROS 1 // (to stop VC2012 complaining)
+# endif
#endif
#if ! (DOXYGEN || BEAST_COMPILER_SUPPORTS_NULLPTR)
- #ifdef nullptr
- #undef nullptr
- #endif
- #define nullptr (0)
+#ifdef nullptr
+#undef nullptr
+#endif
+#define nullptr (0)
#endif
#if ! (DOXYGEN || BEAST_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL)
- #undef override
- #define override
+#undef override
+#define override
#endif
-#endif // BEAST_PLATFORMDEFS_BEASTHEADER
+#endif
diff --git a/modules/beast_core/system/beast_StandardHeader.h b/modules/beast_core/system/beast_StandardHeader.h
index a3b81c3b1..f2ee59a2e 100644
--- a/modules/beast_core/system/beast_StandardHeader.h
+++ b/modules/beast_core/system/beast_StandardHeader.h
@@ -114,6 +114,8 @@
#if BEAST_MSVC && BEAST_DEBUG
# include
+# include
+# include
#endif
#if BEAST_MSVC
diff --git a/modules/beast_core/threads/beast_Process.h b/modules/beast_core/threads/beast_Process.h
index 05a9f1f36..2eb5044b2 100644
--- a/modules/beast_core/threads/beast_Process.h
+++ b/modules/beast_core/threads/beast_Process.h
@@ -90,11 +90,9 @@ public:
*/
static void lowerPrivilege();
- //==============================================================================
/** Returns true if this process is being hosted by a debugger. */
static bool BEAST_CALLTYPE isRunningUnderDebugger();
-
//==============================================================================
/** Tries to launch the OS's default reader application for a given file or URL. */
static bool openDocument (const String& documentURL, const String& parameters);