General refactoring of beast framework classes

This commit is contained in:
Vinnie Falco
2013-09-12 08:26:25 -07:00
parent 84ef06e35c
commit 02acf7d6d0
26 changed files with 514 additions and 306 deletions

View File

@@ -153,8 +153,8 @@
<ClInclude Include="..\..\modules\beast_core\containers\beast_Variant.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_Debug.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_Error.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_FatalError.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_ProtectedCall.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\ProtectedCall.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_FPUFlags.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_LeakChecked.h" />
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_SafeBool.h" />
@@ -211,11 +211,11 @@
<ClInclude Include="..\..\modules\beast_core\memory\SharedObject.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_ScopedPointer.h" />
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_StaticObject.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_Uncopyable.h" />
<ClInclude Include="..\..\modules\beast_core\memory\beast_WeakReference.h" />
<ClInclude Include="..\..\modules\beast_core\memory\SharedPtr.h" />
<ClInclude Include="..\..\modules\beast_core\misc\beast_Main.h" />
<ClInclude Include="..\..\modules\beast_core\memory\StaticObject.h" />
<ClInclude Include="..\..\modules\beast_core\misc\Main.h" />
<ClInclude Include="..\..\modules\beast_core\misc\beast_Result.h" />
<ClInclude Include="..\..\modules\beast_core\misc\beast_Uuid.h" />
<ClInclude Include="..\..\modules\beast_core\misc\beast_WindowsRegistry.h" />
@@ -302,7 +302,7 @@
<ClInclude Include="..\..\modules\beast_core\thread\MutexTraits.h" />
<ClInclude Include="..\..\modules\beast_core\thread\TrackedMutex.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformanceCounter.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformedAtExit.h" />
<ClInclude Include="..\..\modules\beast_core\time\AtExitHook.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_RelativeTime.h" />
<ClInclude Include="..\..\modules\beast_core\time\beast_Time.h" />
<ClInclude Include="..\..\modules\beast_core\xml\beast_XmlDocument.h" />
@@ -557,6 +557,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\Assert.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>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_Debug.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -569,11 +575,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_FatalError.cpp">
<ClCompile Include="..\..\modules\beast_core\diagnostic\FatalError.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_ProtectedCall.cpp">
<ClCompile Include="..\..\modules\beast_core\diagnostic\ProtectedCall.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>
@@ -723,7 +729,13 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\beast_Main.cpp">
<ClCompile Include="..\..\modules\beast_core\memory\StaticObject.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>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\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>
@@ -1131,7 +1143,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\time\beast_PerformedAtExit.cpp">
<ClCompile Include="..\..\modules\beast_core\time\AtExitHook.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

@@ -527,9 +527,6 @@
<ClInclude Include="..\..\modules\beast_core\threads\beast_SpinDelay.h">
<Filter>beast_core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\memory\beast_StaticObject.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\containers\beast_SharedTable.h">
<Filter>beast_core\containers</Filter>
</ClInclude>
@@ -560,9 +557,6 @@
<ClInclude Include="..\..\modules\beast_core\maths\beast_Interval.h">
<Filter>beast_core\maths</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformedAtExit.h">
<Filter>beast_core\time</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_UnitTest.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
@@ -662,18 +656,9 @@
<ClInclude Include="..\..\modules\beast_core\maths\beast_MurmurHash.h">
<Filter>beast_core\maths</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_ProtectedCall.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\misc\beast_Main.h">
<Filter>beast_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\text\beast_LexicalCast.h">
<Filter>beast_core\text</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_FatalError.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\beast_SemanticVersion.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
@@ -1025,6 +1010,21 @@
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\time\AtExitHook.h">
<Filter>beast_core\time</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\misc\Main.h">
<Filter>beast_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\ProtectedCall.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\memory\StaticObject.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp">
@@ -1300,9 +1300,6 @@
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_FPUFlags.cpp">
<Filter>beast_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\time\beast_PerformedAtExit.cpp">
<Filter>beast_core\time</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_UnitTest.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
@@ -1369,18 +1366,9 @@
<ClCompile Include="..\..\modules\beast_core\maths\beast_MurmurHash.cpp">
<Filter>beast_core\maths</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_ProtectedCall.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\beast_Main.cpp">
<Filter>beast_core\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\text\beast_LexicalCast.cpp">
<Filter>beast_core\text</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_FatalError.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\beast_SemanticVersion.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
@@ -1540,6 +1528,24 @@
<ClCompile Include="..\..\modules\beast_asio\beast_asio.cpp">
<Filter>beast_asio</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\time\AtExitHook.cpp">
<Filter>beast_core\time</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\misc\Main.cpp">
<Filter>beast_core\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\ProtectedCall.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\FatalError.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\memory\StaticObject.cpp">
<Filter>beast_core\memory</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\diagnostic\Assert.cpp">
<Filter>beast_core\diagnostic</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\TODO.txt" />

View File

@@ -149,10 +149,10 @@ namespace beast
#include "diagnostic/beast_Debug.cpp"
#include "diagnostic/beast_Error.cpp"
#include "diagnostic/beast_FatalError.cpp"
#include "diagnostic/FatalError.cpp"
#include "diagnostic/beast_FPUFlags.cpp"
#include "diagnostic/beast_LeakChecked.cpp"
#include "diagnostic/beast_ProtectedCall.cpp"
#include "diagnostic/ProtectedCall.cpp"
#include "diagnostic/beast_SemanticVersion.cpp"
#include "diagnostic/beast_UnitTest.cpp"
#include "diagnostic/beast_UnitTestUtilities.cpp"
@@ -180,8 +180,9 @@ namespace beast
#include "memory/beast_FifoFreeStoreWithoutTLS.cpp"
#include "memory/beast_GlobalPagedFreeStore.cpp"
#include "memory/beast_PagedFreeStore.cpp"
#include "memory/StaticObject.cpp"
#include "misc/beast_Main.cpp"
#include "misc/Main.cpp"
#include "misc/beast_Result.cpp"
#include "misc/beast_Uuid.cpp"
@@ -232,7 +233,7 @@ namespace beast
#include "threads/beast_TimeSliceThread.cpp"
#include "time/beast_PerformanceCounter.cpp"
#include "time/beast_PerformedAtExit.cpp"
#include "time/AtExitHook.cpp"
#include "time/beast_RelativeTime.cpp"
#include "time/beast_Time.cpp"

View File

@@ -172,10 +172,14 @@ Some files contain portions of these external projects, licensed separately:
@copyright Provided under the [ISC LIcense][11]
*/
// TargetPlatform.h should not use anything from BeastConfig.h
#include "system/TargetPlatform.h"
#include "system/BeastConfigCheck.h"
# include "system/BeforeBoost.h"
# include "system/BoostIncludes.h"
#include "system/FunctionalIncludes.h"
#include "system/PlatformDefs.h"
#include "system/StandardHeader.h"
#if BEAST_MSVC
@@ -261,8 +265,6 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
# include "containers/detail/removecv.h"
#include "containers/detail/copyconst.h"
#include "system/PlatformDefs.h"
#include "system/TargetPlatform.h"
#include "diagnostic/beast_Throw.h"
#include "system/Functional.h"
#include "memory/beast_AtomicCounter.h"
@@ -272,12 +274,12 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "containers/List.h"
#include "containers/beast_LockFreeStack.h"
#include "threads/beast_SpinDelay.h"
#include "memory/beast_StaticObject.h"
#include "memory/StaticObject.h"
#include "text/StringCharPointerType.h"
#include "text/StringFromNumber.h"
#include "text/beast_String.h"
#include "time/beast_PerformedAtExit.h"
#include "time/AtExitHook.h"
#include "diagnostic/beast_LeakChecked.h"
#include "time/beast_RelativeTime.h"
#include "time/beast_Time.h"
@@ -304,7 +306,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "threads/beast_ThreadLocalValue.h"
#include "thread/MutexTraits.h"
#include "thread/TrackedMutex.h"
#include "diagnostic/beast_FatalError.h"
#include "diagnostic/FatalError.h"
#include "diagnostic/beast_Error.h"
#include "diagnostic/beast_Debug.h"
#include "text/beast_LexicalCast.h"
@@ -317,7 +319,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "memory/SharedObject.h"
#include "memory/SharedPtr.h"
#include "functional/SharedFunction.h"
#include "diagnostic/beast_ProtectedCall.h"
#include "diagnostic/ProtectedCall.h"
#include "containers/beast_AbstractFifo.h"
#include "text/beast_Identifier.h"
#include "containers/beast_Variant.h"
@@ -366,7 +368,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "memory/SharedSingleton.h"
#include "memory/beast_WeakReference.h"
#include "memory/beast_RecycledObjectPool.h"
#include "misc/beast_Main.h"
#include "misc/Main.h"
#include "misc/beast_Uuid.h"
#include "misc/beast_WindowsRegistry.h"
#include "network/beast_IPAddress.h"

View File

@@ -66,16 +66,19 @@ String FatalError::Reporter::formatFilePath (char const* filePath)
//------------------------------------------------------------------------------
Static::Storage <Atomic <FatalError::Reporter*>, FatalError> FatalError::s_reporter;
FatalError::Reporter *FatalError::s_reporter;
void FatalError::setReporter (Reporter& reporter)
/** Returns the current fatal error reporter. */
FatalError::Reporter* FatalError::getReporter ()
{
s_reporter->compareAndSetBool (&reporter, nullptr);
return s_reporter;
}
void FatalError::resetReporter (Reporter& reporter)
FatalError::Reporter* FatalError::setReporter (Reporter* reporter)
{
s_reporter->compareAndSetBool (nullptr, &reporter);
Reporter* const previous (s_reporter);
s_reporter = reporter;
return previous;
}
FatalError::FatalError (char const* message, char const* fileName, int lineNumber)
@@ -94,7 +97,7 @@ FatalError::FatalError (char const* message, char const* fileName, int lineNumbe
char const* const szFileName = fileNameString.toRawUTF8 ();
Reporter* const reporter = s_reporter->get ();
Reporter* const reporter (s_reporter);
if (reporter != nullptr)
{

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_FATALERROR_H_INCLUDED
#define BEAST_FATALERROR_H_INCLUDED
#ifndef BEAST_CORE_FATALERROR_H_INCLUDED
#define BEAST_CORE_FATALERROR_H_INCLUDED
/** Signal a fatal error.
@@ -109,6 +109,9 @@ public:
virtual String formatFilePath (char const* filePath);
};
/** Returns the current fatal error reporter. */
static Reporter* getReporter ();
/** Set the fatal error reporter.
Note that if a fatal error is raised during the construction of
@@ -122,16 +125,11 @@ public:
If a reporter was previously set, this routine will do nothing.
@return The previous Reporter (Which may be null).
@see SharedSingleton, Reporter
*/
static void setReporter (Reporter& reporter);
/** Clear the fatal error reporter.
If the current reporter is the same as the one passed in, this
will remove the reporter.
*/
static void resetReporter (Reporter& reporter);
static Reporter* setReporter (Reporter* reporter);
/** Raise a fatal error.
@@ -145,7 +143,7 @@ public:
FatalError (char const* message, char const* filePath, int lineNumber);
private:
static Static::Storage <Atomic <Reporter*>, FatalError> s_reporter;
static Reporter* s_reporter;
};
//------------------------------------------------------------------------------

View File

@@ -297,19 +297,18 @@ ProtectedCall::DefaultHandler::LockType ProtectedCall::DefaultHandler::s_mutex;
//------------------------------------------------------------------------------
Static::Storage <Atomic <ProtectedCall::Handler const*>, ProtectedCall>
ProtectedCall::s_handler;
ProtectedCall::Handler const* ProtectedCall::s_handler;
void ProtectedCall::setHandler (Handler const& handler)
{
s_handler->set (&handler);
s_handler = &handler;
}
void ProtectedCall::call (Call& c)
{
static DefaultHandler defaultHandler;
Handler const* handler = s_handler->get ();
Handler const* handler = s_handler;
if (handler == nullptr)
handler = &defaultHandler;

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_PROTECTEDCALL_H_INCLUDED
#define BEAST_PROTECTEDCALL_H_INCLUDED
#ifndef BEAST_CORE_PROTECTEDCALL_H_INCLUDED
#define BEAST_CORE_PROTECTEDCALL_H_INCLUDED
/** Call a function in a protected exception context.
@@ -141,7 +141,7 @@ private:
void call (Call& call);
private:
static Static::Storage <Atomic <Handler const*>, ProtectedCall> s_handler;
static Handler const* s_handler;
};
#endif

View File

@@ -296,19 +296,65 @@ String commandLineToString (const String& commandLine)
//------------------------------------------------------------------------------
// A simple unit test to determine the diagnostic settings in a build.
//
class DebugTests : public UnitTest
{
public:
DebugTests () : UnitTest ("Debug", "beast", runManual)
static int envDebug ()
{
#ifdef _DEBUG
return 1;
#else
return 0;
#endif
}
static int beastDebug ()
{
#ifdef BEAST_DEBUG
return BEAST_DEBUG;
#else
return 0;
#endif
}
static int beastForceDebug ()
{
#ifdef BEAST_FORCE_DEBUG
return BEAST_FORCE_DEBUG;
#else
return 0;
#endif
}
static int beastCatchExceptions ()
{
#ifdef BEAST_CATCH_UNHANDLED_EXCEPTIONS
return BEAST_CATCH_UNHANDLED_EXCEPTIONS;
#else
return 0;
#endif
}
void runTest ()
{
beginTestCase ("bassert");
beginTestCase ("diagnostics");
logMessage ("operatingSystemName = '" + SystemStats::getOperatingSystemName () + "'");
logMessage ("_DEBUG = " + String::fromNumber (envDebug ()));
logMessage ("BEAST_DEBUG = " + String::fromNumber (beastDebug ()));
logMessage ("BEAST_FORCE_DEBUG = " + String::fromNumber (beastForceDebug ()));
logMessage ("BEAST_CATCH_UNHANDLED_EXCEPTIONS = " + String::fromNumber (beastCatchExceptions ()));
bassertfalse;
fail ();
}
DebugTests () : UnitTest ("Debug", "beast", runManual)
{
}
};
static DebugTests debugTests;

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
namespace Implemented
namespace detail
{
class LeakCheckedBase::CounterBase::Singleton

View File

@@ -20,18 +20,23 @@
#ifndef BEAST_LEAKCHECKED_H_INCLUDED
#define BEAST_LEAKCHECKED_H_INCLUDED
namespace Implemented
namespace detail
{
class BEAST_API LeakCheckedBase
class LeakCheckedBase
{
public:
static void checkForLeaks ();
protected:
class CounterBase : public LockFreeStack <CounterBase>::Node
{
public:
CounterBase ();
virtual ~CounterBase () { }
virtual ~CounterBase ()
{
}
inline int increment ()
{
@@ -47,24 +52,15 @@ protected:
private:
void checkForLeaks ();
virtual void checkPureVirtual () const = 0;
private:
friend class LeakCheckedBase;
class Singleton;
friend class LeakCheckedBase;
Atomic <int> m_count;
};
protected:
static void reportDanglingPointer (char const* objectName);
private:
friend class PerformedAtExit::ExitHook;
static void checkForLeaks ();
};
//------------------------------------------------------------------------------
@@ -129,18 +125,7 @@ private:
//
static Counter& getCounter () noexcept
{
static Counter* volatile s_instance;
static Static::Initializer s_initializer;
if (s_initializer.beginConstruction ())
{
static char s_storage [sizeof (Counter)];
s_instance = new (s_storage) Counter;
s_initializer.endConstruction ();
}
return *s_instance;
return StaticObject <Counter>::get();
}
};
@@ -148,35 +133,40 @@ private:
//------------------------------------------------------------------------------
namespace Dummy
namespace detail
{
class BEAST_API LeakCheckedBase
namespace disabled
{
private:
friend class PerformedAtExit;
class LeakCheckedBase
{
public:
static void checkForLeaks () { }
static void checkForLeaks ()
{
}
};
template <class Object>
struct LeakChecked : LeakCheckedBase
class LeakChecked : public LeakCheckedBase
{
public:
};
}
}
//------------------------------------------------------------------------------
// Lift the corresponding implementation
// Lift the appropriate implementation into our namespace
//
#if BEAST_CHECK_MEMORY_LEAKS
using Implemented::LeakChecked;
using Implemented::LeakCheckedBase;
using detail::LeakChecked;
using detail::LeakCheckedBase;
#else
using Dummy::LeakChecked;
using Dummy::LeakCheckedBase;
using detail::disabled::LeakChecked;
using detail::disabled::LeakCheckedBase;
#endif
#endif

View File

@@ -86,6 +86,7 @@ public:
instance = staticData.instance;
if (instance == nullptr)
{
bassert (lifetime == SingletonLifetime::createOnDemand || ! staticData.destructorCalled);
staticData.instance = &staticData.object;
::new (staticData.instance) SharedSingleton (lifetime);
instance = staticData.instance;
@@ -107,7 +108,7 @@ private:
{
}
void performAtExit ()
void onExit ()
{
if (m_lifetime == SingletonLifetime::persistAfterCreation)
this->decReferenceCount ();
@@ -132,6 +133,7 @@ private:
{
callDestructor = true;
staticData.instance = nullptr;
staticData.destructorCalled = true;
}
}
@@ -145,31 +147,16 @@ private:
typedef SpinLock LockType;
class ExitHook : public PerformedAtExit
{
public:
explicit ExitHook (SharedSingleton* owner)
: m_owner (owner)
{
}
void performAtExit ()
{
m_owner->performAtExit();
}
private:
SharedSingleton* m_owner;
};
// This structure gets zero-filled at static initialization time.
// No constructors are called.
//
struct StaticData
class StaticData : public Uncopyable
{
public:
LockType mutex;
SharedSingleton* instance;
SharedSingleton object;
bool destructorCalled;
private:
StaticData();
@@ -183,9 +170,10 @@ private:
}
friend class SharedPtr <SharedSingleton>;
friend class AtExitMemberHook <SharedSingleton>;
SingletonLifetime::Lifetime m_lifetime;
ExitHook m_exitHook;
AtExitMemberHook <SharedSingleton> m_exitHook;
};
//------------------------------------------------------------------------------

View File

@@ -17,36 +17,18 @@
*/
//==============================================================================
#ifndef BEAST_PERFORMEDATEXIT_H_INCLUDED
#define BEAST_PERFORMEDATEXIT_H_INCLUDED
/*============================================================================*/
/**
Perform an action at program exit
To use, derive your class from PerformedAtExit, and override `performAtExit()`.
The call will be made during the destruction of objects with static storage
duration, before LeakChecked performs its diagnostics.
@ingroup beast_core
*/
// VFALCO TODO Make the linked list element a private type and use composition
// instead of inheritance, so that PerformedAtExit doesn't expose
// lock free stack node interfaces.
//
class BEAST_API PerformedAtExit : public LockFreeStack <PerformedAtExit>::Node
namespace detail
{
public:
class ExitHook;
protected:
PerformedAtExit ();
virtual ~PerformedAtExit () { }
// This is here so we don't need the Thread class declaration
void staticObjectWait (std::size_t n)
{
// Wait for initialization
Thread::yield ();
if (n > 10)
Thread::sleep (1);
else if (n > 100)
Thread::sleep (10);
}
protected:
/** Called at program exit.
*/
virtual void performAtExit () = 0;
};
#endif
}

View File

@@ -112,61 +112,86 @@ private:
template <class ObjectType, class Tag>
char Storage <ObjectType, Tag>::s_storage [sizeof (ObjectType)];
}
//------------------------------------------------------------------------------
// Provides a thread safe flag for indicating if and when
// initialization is required for an object with static storage duration.
//
class Initializer
namespace detail
{
extern void staticObjectWait (std::size_t n);
}
/** Wrapper to produce an object with static storage duration.
The object is constructed in a thread-safe fashion when the get function
is first called. Note that the destructor for Object is never called. To
invoke the destructor, use the AtExitHook facility (with caution).
The Tag parameter allows multiple instances of the same Object type, by
using different tags.
Object must meet these requirements:
DefaultConstructible
@see AtExitHook
*/
template <class Object, typename Tag = void>
class StaticObject
{
public:
// If the condition is not initialized, the first caller will
// receive true, while concurrent callers get blocked until
// initialization completes.
//
bool beginConstruction ()
static Object& get ()
{
bool needsInitialization = false;
StaticData& staticData (StaticData::get());
if (m_state.get () != stateInitialized)
if (staticData.state.get() != initialized)
{
if (m_state.compareAndSetBool (stateInitializing, stateUninitialized))
if (staticData.state.compareAndSetBool (initializing, uninitialized))
{
needsInitialization = true;
// Initialize the object.
::new (&staticData.object) Object;
staticData.state = initialized;
}
else
{
SpinDelay delay;
do
for (std::size_t n = 0; staticData.state.get() != initialized; ++n)
{
delay.pause ();
detail::staticObjectWait (n);
}
while (m_state.get () != stateInitialized);
}
}
return needsInitialization;
}
// Called to signal that the initialization is complete
//
void endConstruction ()
{
m_state.set (stateInitialized);
return staticData.object;
}
private:
enum
{
stateUninitialized = 0, // must be zero
stateInitializing,
stateInitialized
uninitialized = 0, // must be zero to function properly
initializing,
initialized
};
Atomic <int> m_state;
// This structure gets zero-filled at static initialization time.
// No constructors are called.
//
class StaticData : public Uncopyable
{
public:
Atomic <int> state;
Object object;
static StaticData& get ()
{
static uint8 storage [sizeof (StaticData)];
return *(reinterpret_cast <StaticData*> (&storage [0]));
}
private:
StaticData();
~StaticData();
};
};
}
#endif

View File

@@ -17,31 +17,33 @@
*/
//==============================================================================
Static::Storage <Atomic <Main*>, Main> Main::s_instance;
Main* Main::s_instance;
Main::Main ()
{
bool const replaced = s_instance->compareAndSetBool (this, nullptr);
// If this happens it means there are two instances of Main!
if (! replaced)
FatalError ("Multiple instances of Main", __FILE__, __LINE__);
check_precondition (s_instance == nullptr);
s_instance = this;
}
Main::~Main ()
{
s_instance->set (nullptr);
s_instance = nullptr;
}
Main& Main::getInstance ()
{
bassert (s_instance->get () != nullptr);
bassert (s_instance != nullptr);
return *s_instance->get ();
return *s_instance;
}
void Main::runStartupUnitTests ()
int Main::runStartupUnitTests ()
{
int exitCode = EXIT_SUCCESS;
struct StartupUnitTests : UnitTests
{
void logMessage (String const&)
@@ -105,15 +107,20 @@ void Main::runStartupUnitTests ()
{
tests.reportResults ();
tests.log ("Terminating due to failed startup tests");
tests.log ("Terminating with an error due to failed startup tests.");
Process::terminate ();
exitCode = EXIT_FAILURE;
}
return exitCode;
}
int Main::runFromMain (int argc, char const* const* argv)
{
runStartupUnitTests ();
int exitCode (runStartupUnitTests ());
return run (argc, argv);
if (exitCode == EXIT_SUCCESS)
exitCode = run (argc, argv);
return exitCode;
}

View File

@@ -17,15 +17,14 @@
*/
//==============================================================================
#ifndef BEAST_MAIN_H_INCLUDED
#define BEAST_MAIN_H_INCLUDED
/** Represents a command line program's entry point.
#ifndef BEAST_CORE_MAIN_H_INCLUDED
#define BEAST_CORE_MAIN_H_INCLUDED
/** Represents a command line program's entry point
To use this, derive your class from @ref Main and implement the
function run ();
*/
class BEAST_API Main : public Uncopyable
class Main : public Uncopyable
{
public:
Main ();
@@ -70,10 +69,10 @@ protected:
virtual int run (int argc, char const* const* argv) = 0;
private:
void runStartupUnitTests ();
int runStartupUnitTests ();
private:
static Static::Storage <Atomic <Main*>, Main> s_instance;
static Main* s_instance;
};
#endif

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_CORE_SYSTEM_BEASTCONFIGCHECK_H_INCLUDED
#define BEAST_CORE_SYSTEM_BEASTCONFIGCHECK_H_INCLUDED
#ifndef BEAST_CORE_BEASTCONFIGCHECK_H_INCLUDED
#define BEAST_CORE_BEASTCONFIGCHECK_H_INCLUDED
// This file makes sure that BeastConfig.h was included.
// It also sets defaults for all config options.

View File

@@ -20,14 +20,14 @@
#ifndef BEAST_CORE_SYSTEM_BEFOREBOOST_H_INCLUDED
#define BEAST_CORE_SYSTEM_BEFOREBOOST_H_INCLUDED
// TargetPlatform.h should not use anything from BeastConfig.h
#include "TargetPlatform.h"
#include "BeastConfigCheck.h"
// This file should be included before including any boost headers.
// If you don't include this file, and you include boost headers,
// Beast will generate a compile error with an explanation of why.
#include "TargetPlatform.h"
#include "BeastConfigCheck.h"
#if BEAST_USE_BOOST_FEATURES
// Prevent <boost/bind/placeholders.hpp> from being included

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_CORE_SYSTEM_BOOSTINCLUDES_H_INCLUDED
#define BEAST_CORE_SYSTEM_BOOSTINCLUDES_H_INCLUDED
#ifndef BEAST_CORE_BOOSTINCLUDES_H_INCLUDED
#define BEAST_CORE_BOOSTINCLUDES_H_INCLUDED
#if BEAST_USE_BOOST_FEATURES

View File

@@ -21,16 +21,14 @@
*/
//==============================================================================
#ifndef BEAST_PLATFORMDEFS_H_INCLUDED
#define BEAST_PLATFORMDEFS_H_INCLUDED
#ifndef BEAST_CORE_PLATFORMDEFS_H_INCLUDED
#define BEAST_CORE_PLATFORMDEFS_H_INCLUDED
// This file defines miscellaneous macros for debugging, assertions, etc.
#ifdef BEAST_FORCE_DEBUG
#if BEAST_FORCE_DEBUG
# undef BEAST_DEBUG
# if BEAST_FORCE_DEBUG
# define BEAST_DEBUG 1
# endif
# define BEAST_DEBUG 1
#endif
/** This macro defines the C calling convention used as the standard for Beast calls.

View File

@@ -47,7 +47,9 @@
//------------------------------------------------------------------------------
#include "PlatformDefs.h"
#ifndef BEAST_CORE_PLATFORMDEFS_H_INCLUDED
#error "PlatformDefs.h must be included first"
#endif
// Now we'll include some common OS headers..
#if BEAST_MSVC

View File

@@ -21,8 +21,8 @@
*/
//==============================================================================
#ifndef BEAST_TARGETPLATFORM_H_INCLUDED
#define BEAST_TARGETPLATFORM_H_INCLUDED
#ifndef BEAST_CORE_TARGETPLATFORM_H_INCLUDED
#define BEAST_CORE_TARGETPLATFORM_H_INCLUDED
//==============================================================================
/* This file figures out which platform is being built, and defines some macros
@@ -213,4 +213,5 @@
#define BEAST_PP_STR1_(x) BEAST_PP_STR2_(x)
#define BEAST_FILEANDLINE_ __FILE__ "(" BEAST_PP_STR1_(__LINE__) "): warning:"
#endif // BEAST_TARGETPLATFORM_H_INCLUDED
#endif

View File

@@ -30,7 +30,7 @@ private:
m_thread.stop (true);
}
void performAtExit ()
void onExit ()
{
//delete this;
}

View File

@@ -0,0 +1,135 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
// Manages the list of hooks, and calls
// whoever is in the list at exit time.
//
class AtExitHook::Manager
{
public:
Manager ()
: m_didStaticDestruction (false)
{
}
static inline Manager& get ()
{
return StaticObject <Manager>::get();
}
void insert (Item& item)
{
ScopedLockType lock (m_mutex);
// Adding a new AtExitHook during or after the destruction
// of objects with static storage duration has taken place?
// Surely something has gone wrong.
//
bassert (! m_didStaticDestruction);
m_list.push_front (item);
}
void erase (Item& item)
{
ScopedLockType lock (m_mutex);
m_list.erase (m_list.iterator_to (item));
}
private:
// Called at program exit when destructors for objects
// with static storage duration are invoked.
//
void doStaticDetruction ()
{
// In theory this shouldn't be needed (?)
ScopedLockType lock (m_mutex);
bassert (! m_didStaticDestruction);
for (List <Item>::iterator iter (m_list.begin()); iter != m_list.end();)
{
Item& item (*iter++);
AtExitHook* const hook (item.hook ());
hook->onExit ();
}
// Now do the leak checking
//
LeakCheckedBase::checkForLeaks ();
}
struct StaticDestructor
{
~StaticDestructor ()
{
Manager::get().doStaticDetruction();
}
};
typedef CriticalSection MutexType;
typedef MutexType::ScopedLockType ScopedLockType;
static StaticDestructor s_staticDestructor;
MutexType m_mutex;
List <Item> m_list;
bool m_didStaticDestruction;
};
// This is an object with static storage duration.
// When it gets destroyed, we will call into the Manager to
// call all of the AtExitHook items in the list.
//
AtExitHook::Manager::StaticDestructor AtExitHook::Manager::s_staticDestructor;
//------------------------------------------------------------------------------
AtExitHook::Item::Item (AtExitHook* hook)
: m_hook (hook)
{
}
AtExitHook* AtExitHook::Item::hook ()
{
return m_hook;
}
//------------------------------------------------------------------------------
AtExitHook::AtExitHook ()
: m_item (this)
{
#if BEAST_IOS
// Patrick Dehne:
// AtExitHook::Manager::insert crashes on iOS
// if the storage is not accessed before it is used.
//
// VFALCO TODO Figure out why and fix it cleanly if needed.
//
char* hack = AtExitHook::Manager::s_list.s_storage;
#endif
Manager::get().insert (m_item);
}
AtExitHook::~AtExitHook ()
{
Manager::get().erase (m_item);
}

View File

@@ -0,0 +1,88 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CORE_ATEXITHOOK_H_INCLUDED
#define BEAST_CORE_ATEXITHOOK_H_INCLUDED
/** Hook for performing activity on program exit.
These hooks execute when objects with static storage duration are
destroyed. The hooks are called in the reverse order that they were
created.
To use, derive your class from AtExitHook and implement onExit.
Alternatively, add AtExitMemberHook as a data member of your class and
then provide your own onExit function with this signature:
@code
void onExit ()
@endcode
@see AtExitMemberHook
*/
/** @{ */
class AtExitHook
{
protected:
AtExitHook ();
virtual ~AtExitHook ();
protected:
/** Called at program exit. */
virtual void onExit () = 0;
private:
class Manager;
class Item : public List <Item>::Node
{
public:
explicit Item (AtExitHook* hook);
AtExitHook* hook ();
private:
AtExitHook* m_hook;
};
Item m_item;
};
/** Helper for utilizing the AtExitHook as a data member.
*/
template <class Object>
class AtExitMemberHook : public AtExitHook
{
public:
explicit AtExitMemberHook (Object* owner) : m_owner (owner)
{
}
private:
void onExit ()
{
m_owner->onExit ();
}
Object* m_owner;
};
/** @} */
#endif

View File

@@ -1,74 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
class PerformedAtExit::ExitHook
{
public:
typedef Static::Storage <LockFreeStack <PerformedAtExit>, PerformedAtExit> StackType;
private:
~ExitHook ()
{
// Call all PerformedAtExit objects
//
PerformedAtExit* object = s_list->pop_front ();
while (object != nullptr)
{
object->performAtExit ();
object = s_list->pop_front ();
}
// Now do the leak checking
//
LeakCheckedBase::checkForLeaks ();
}
public:
static void push_front (PerformedAtExit* object)
{
s_list->push_front (object);
}
private:
friend class PerformedAtExit;
static StackType s_list;
static ExitHook s_performer;
};
PerformedAtExit::ExitHook PerformedAtExit::ExitHook::s_performer;
PerformedAtExit::ExitHook::StackType PerformedAtExit::ExitHook::s_list;
PerformedAtExit::PerformedAtExit ()
{
#if BEAST_IOS
// Patrick Dehne:
// PerformedAtExit::ExitHook::push_front crashes on iOS
// if s_storage is not accessed before used
//
// VFALCO TODO Figure out why and fix it cleanly if needed.
//
char* hack = PerformedAtExit::ExitHook::s_list.s_storage;
#endif
ExitHook::push_front (this);
}