Tidy up and activate the MSVC Debug Heap

This commit is contained in:
Vinnie Falco
2013-06-29 18:23:59 -07:00
parent fe8834a52a
commit f881ee96f9
24 changed files with 1094 additions and 308 deletions

View File

@@ -20,30 +20,109 @@
#ifndef BEAST_BEASTCONFIG_H_INCLUDED
#define BEAST_BEASTCONFIG_H_INCLUDED
// beast_core flags:
/** Configuration file for Beast.
#ifndef BEAST_FORCE_DEBUG
//#define BEAST_FORCE_DEBUG
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
Normally, BEAST_DEBUG is set to 1 or 0 based on compiler and project
settings, but if you define this value, you can override this to force it
to be true or false.
*/
#ifndef BEAST_FORCE_DEBUG
//#define BEAST_FORCE_DEBUG 0
#endif
#ifndef BEAST_LOG_ASSERTIONS
//#define BEAST_LOG_ASSERTIONS 1
//------------------------------------------------------------------------------
/** Config: BEAST_LOG_ASSERTIONS
If this flag is enabled, the the bassert and bassertfalse macros will always
use Logger::writeToLog() to write a message when an assertion happens.
Enabling it will also leave this turned on in release builds. When it's
disabled, however, the bassert and bassertfalse macros will not be compiled
in a release build.
@see bassert, bassertfalse, Logger
*/
#ifndef BEAST_LOG_ASSERTIONS
//#define BEAST_LOG_ASSERTIONS 0
#endif
//------------------------------------------------------------------------------
/** Config: BEAST_CHECK_MEMORY_LEAKS
Enables a memory-leak check for certain objects when the app terminates.
See the LeakedObjectDetector and LeakChecked classes, and the
BEAST_LEAK_DETECTOR macro for more details about enabling leak checking for
specific classes.
*/
#ifndef BEAST_CHECK_MEMORY_LEAKS
#define BEAST_CHECK_MEMORY_LEAKS 1
#endif
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//#define BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//------------------------------------------------------------------------------
/** Config: BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
In a Visual C++ build, this can be used to stop the required system libs
being automatically added to the link stage.
*/
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//#define BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES 1
#endif
// beast_basics flags
//------------------------------------------------------------------------------
/** Config: BEAST_INCLUDE_ZLIB_CODE
This can be used to disable Beast's embedded 3rd-party zlib code.
You might need to tweak this if you're linking to an external zlib library in your app,
but for normal apps, this option should be left alone.
If you disable this, you might also want to set a value for BEAST_ZLIB_INCLUDE_PATH, to
specify the path where your zlib headers live.
*/
#ifndef BEAST_INCLUDE_ZLIB_CODE
//#define BEAST_INCLUDE_ZLIB_CODE 0
#endif
#ifndef BEAST_ZLIB_INCLUDE_PATH
#define BEAST_ZLIB_INCLUDE_PATH <zlib.h>
#endif
//------------------------------------------------------------------------------
/** Config: BEAST_BOOST_IS_AVAILABLE
This activates boost specific features and improvements.
*/
#ifndef BEAST_BOOST_IS_AVAILABLE
#define BEAST_BOOST_IS_AVAILABLE 1
#endif
/** 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
#define BEAST_USE_LEAKCHECKED BEAST_CHECK_MEMORY_LEAKS
#define BEAST_USE_LEAKCHECKED 1
#endif
#endif

View File

@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_VARIADIC_MAX=10;_WIN32_WINNT=0x0600;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_VARIADIC_MAX=10;_WIN32_WINNT=0x0600;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>$(RepoDir);$(RepoDir)\src\cpp\protobuf\src;$(RepoDir)\src\cpp\protobuf\vsprojects;$(RepoDir)\build\proto;$(RepoDir)\Subtrees;$(RepoDir)\Subtrees\leveldb;$(RepoDir)\Subtrees\leveldb\include;$(RepoDir)\Subtrees\beast;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

View File

@@ -1200,7 +1200,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\cpp\ripple\main.cpp">
<ClCompile Include="..\..\src\cpp\ripple\ripple_Main.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>

View File

@@ -582,9 +582,6 @@
<ClCompile Include="..\..\src\cpp\ripple\ParameterTable.cpp">
<Filter>1. Modules\ripple_app\_unfactored</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cpp\ripple\main.cpp">
<Filter>1. Modules\ripple_app\_unfactored</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_basics\utility\ripple_CountedObject.cpp">
<Filter>1. Modules\ripple_basics\utility</Filter>
</ClCompile>
@@ -948,6 +945,9 @@
<ClCompile Include="..\..\modules\ripple_data\protocol\ripple_STAmountUnitTests.cpp">
<Filter>1. Modules\ripple_data\protocol</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cpp\ripple\ripple_Main.cpp">
<Filter>1. Modules\ripple_app\_unfactored</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\cpp\protobuf\src\google\protobuf\service.h">

View File

@@ -6,6 +6,7 @@
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />

View File

@@ -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

View File

@@ -234,64 +234,8 @@ Some files contain portions of these external projects, licensed separately:
#include <boost/thread/tss.hpp>
#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 <crtdbg.h>
#include <stdlib.h>
#include <malloc.h>
#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.

View File

@@ -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;

View File

@@ -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 <ThreadWithCallQueue>
{
public:
/** Entry points for a ThreadWithCallQueue.

View File

@@ -102,8 +102,39 @@
#include <android/log.h>
#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

View File

@@ -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

View File

@@ -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 ()
{
}

View File

@@ -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 ();
}

View File

@@ -76,7 +76,7 @@ void LeakCheckedBase::CounterBase::detectLeaks ()
if (count > 0)
{
bassertfalse;
//bassertfalse;
DBG ("[LEAK] " << count << " of " << getClassName ());
}
}

View File

@@ -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 <class Exception>
inline void Throw (Exception const& e)
{
// VFALCO TODO Replace with straight JUCE equivalent
Debug::breakPoint ();
throw e;

View File

@@ -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;
}
}

View File

@@ -0,0 +1,648 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 <LPWSTR> (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<Pimpl*> (userInfo))
if (timer->periodMs != 0)
timer->owner.hiResTimerCallback();
}
BEAST_DECLARE_NON_COPYABLE (Pimpl)
};

View File

@@ -285,6 +285,8 @@ bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
return beast_isRunningUnderDebugger();
}
//------------------------------------------------------------------------------
static void* currentModuleHandle = nullptr;
void* Process::getCurrentModuleInstanceHandle() noexcept

View File

@@ -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 <bool b> struct BeastStaticAssert;
template <> struct BeastStaticAssert <true> { static void dummy() {} };
template <bool b> struct BeastStaticAssert;
template <> struct BeastStaticAssert <true> { 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

View File

@@ -114,6 +114,8 @@
#if BEAST_MSVC && BEAST_DEBUG
# include <crtdbg.h>
# include <stdlib.h>
# include <malloc.h>
#endif
#if BEAST_MSVC

View File

@@ -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);

View File

@@ -2,6 +2,12 @@
BEAST TODO
--------------------------------------------------------------------------------
- Fix FifoFreeStoreWithTLS reference counting bug
- Implement a reasonable substitute for boost's thread_local_storage
- Think about doing away with BEAST_CALLTYPE and BEAST_API
- Decide if headers should just include BeastConfig.h instead of making the
host program do it.

View File

@@ -252,7 +252,7 @@ static const uint64 tenTo17m1 = tenTo17 - 1;
#include "src/cpp/ripple/LedgerProposal.cpp"
#include "src/cpp/ripple/LedgerTiming.cpp"
#include "src/cpp/ripple/ripple_LoadManager.cpp"
#include "src/cpp/ripple/main.cpp"
#include "src/cpp/ripple/ripple_Main.cpp"
#include "src/cpp/ripple/ripple_NicknameState.cpp"
#include "src/cpp/ripple/ripple_Offer.cpp"
#include "src/cpp/ripple/OfferCancelTransactor.cpp"

View File

@@ -119,10 +119,30 @@ void printHelp (const po::options_description& desc)
int rippleMain (int argc, char** argv)
{
//
// These debug heap calls do nothing in release or non Visual Studio builds.
//
// Checks the heap at every allocation and deallocation (slow).
Debug::setAlwaysCheckHeap (false);
// Keeps freed memory blocks and fills them with a guard value.
Debug::setHeapDelayedFree (false);
// At exit, reports all memory blocks which have not been freed.
Debug::setHeapReportLeaks (false);
#if 0
// This is some temporary leak checking test code
ThreadWithCallQueue t ("test");
t.start ();
return 0;
#endif
using namespace std;
setCallingThreadName ("main");
int iResult = 0;
int iResult = 0;
po::variables_map vm; // Map of options.
//