diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index 85fdc55d52..72c9a657f0 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -150,6 +150,7 @@ + diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index 0b307e9f47..7e17799be9 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -980,6 +980,9 @@ beast_core\memory + + beast_core\diagnostic + diff --git a/Subtrees/beast/modules/beast_core/beast_core.h b/Subtrees/beast/modules/beast_core/beast_core.h index 87d0144bd8..63401e3db2 100644 --- a/Subtrees/beast/modules/beast_core/beast_core.h +++ b/Subtrees/beast/modules/beast_core/beast_core.h @@ -244,6 +244,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n // Order matters, since headers don't have their own #include lines. // Add new includes to the bottom. +#include "diagnostic/ContractChecks.h" #include "memory/beast_Uncopyable.h" #include "memory/beast_Memory.h" #include "maths/beast_MathsFunctions.h" diff --git a/Subtrees/beast/modules/beast_core/diagnostic/ContractChecks.h b/Subtrees/beast/modules/beast_core/diagnostic/ContractChecks.h new file mode 100644 index 0000000000..b7d9e09a0f --- /dev/null +++ b/Subtrees/beast/modules/beast_core/diagnostic/ContractChecks.h @@ -0,0 +1,100 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_CONTRACTCHECKS_H_INCLUDED +#define BEAST_CONTRACTCHECKS_H_INCLUDED + +#if defined (fatal_error) || \ + defined (fatal_condition) || \ + defined (fatal_assert) || \ + defined (meets_condition) || \ + defined (meets_precondition) || \ + defined (meets_postcondition) || \ + defined (meets_invariant) || \ + defined (check_precondition) || \ + defined (check_postcondition) || \ + defined (check_invariant) +#error "Programming by contract macros cannot be overriden!" +#endif + +extern void reportFatalError (char const* message, char const* fileName, int lineNumber); + +/** Report a fatal error message and terminate the application. + This macro automatically fills in the file and line number + Meets this declaration syntax: + @code inline void fatal_error (char const* message); @endif + @see FatalError +*/ +#define fatal_error(message) reportFatalError (message, __FILE__, __LINE__) + +/** Reports a fatal error message type if the condition is false + The condition is always evaluated regardless of settings. + Meets this declaration syntax: + @code inline void fatal_condition (bool condition, char const* category); @endcode +*/ +#define fatal_condition(condition,category) static_cast \ + (((!!(condition)) || (reportFatalError ( \ + category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), 0))) + +/** Replacement for assert which generates a fatal error if the condition is false. + The condition is always evaluated regardless of compilation settings. + Meets this declaration syntax: + @code inline void fatal_assert (bool condition); @endcode +*/ +#define fatal_assert(condition) fatal_condition(condition,"Assertion") + +/** Reports a fatal error message type if the condition is false + The condition is always evaluated regardless of settings. + Meets this declaration syntax: + @code inline void fatal_condition (bool condition, char const* category); @endcode +*/ +#define meets_condition(condition,category) static_cast \ + (((!!(condition)) || (reportFatalError ( \ + category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), false))) + +/** Condition tests for programming by contract. + The condition is always evaluated regardless of settings, and gets returned. + Meets this declaration syntax: + @code inline bool meets_condition (bool); @endcode +*/ +/** @{ */ +#define meets_precondition(condition) meets_condition(condition,"Pre-condition") +#define meets_postcondition(condition) meets_condition(condition,"Post-condition") +#define meets_invariant(condition) meets_condition(condition,"Invariant") +/** @} */ + +/** Condition tests for programming by contract. + The condition is evaluated only if BEAST_DISABLE_CONTRACT_CHECKS is 0. + Meets this declaration syntax: + @code inline void check_condition (bool); @endcode + @see BEAST_DISABLE_CONTRACT_CHECKS +*/ +/** @{ */ +#if ! BEAST_DISABLE_CONTRACT_CHECKS +# define check_precondition(condition) meets_precondition(condition) +# define check_postcondition(condition) meets_postcondition(condition) +# define check_invariant(condition) meets_invariant(condition) +#else +# define check_precondition(condition) ((void)0) +# define check_postcondition(condition) ((void)0) +# define check_invariant(condition) ((void)0) +#endif +/** @} */ + +#endif diff --git a/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.cpp b/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.cpp index 0023938d37..f3a13aaf54 100644 --- a/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.cpp +++ b/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.cpp @@ -20,7 +20,6 @@ // // FatalError::Reporter // - void FatalError::Reporter::onFatalError ( char const* message, char const* stackBacktrace, char const* filePath, int lineNumber) { @@ -105,6 +104,14 @@ FatalError::FatalError (char const* message, char const* fileName, int lineNumbe Process::terminate (); } +void reportFatalError (char const* message, char const* fileName, int lineNumber) +{ + if (beast::beast_isRunningUnderDebugger()) + beast_breakDebugger; + FatalError (message, fileName, lineNumber); + BEAST_ANALYZER_NORETURN +} + //------------------------------------------------------------------------------ // Yes even this class can have a unit test. It's manually triggered though. diff --git a/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.h b/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.h index 24ce7847dc..87222d244c 100644 --- a/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.h +++ b/Subtrees/beast/modules/beast_core/diagnostic/beast_FatalError.h @@ -150,92 +150,9 @@ private: //------------------------------------------------------------------------------ -#if defined (fatal_error) || \ - defined (fatal_condition) || \ - defined (fatal_assert) || \ - defined (meets_condition) || \ - defined (meets_precondition) || \ - defined (meets_postcondition) || \ - defined (meets_invariant) || \ - defined (check_precondition) || \ - defined (check_postcondition) || \ - defined (check_invariant) -#error "Programming by contract macros cannot be overriden!" -#endif - -//------------------------------------------------------------------------------ - /** Report a fatal error message and terminate the application. Normally you won't call this directly. */ -inline void reportFatalError (char const* message, char const* fileName, int lineNumber) -{ - if (beast::beast_isRunningUnderDebugger()) - beast_breakDebugger; - FatalError (message, fileName, lineNumber); - BEAST_ANALYZER_NORETURN -} - -/** Report a fatal error message and terminate the application. - This macro automatically fills in the file and line number - Meets this declaration syntax: - @code inline void fatal_error (char const* message); @endif - @see FatalError -*/ -#define fatal_error(message) reportFatalError (message, __FILE__, __LINE__) - -/** Reports a fatal error message type if the condition is false - The condition is always evaluated regardless of settings. - Meets this declaration syntax: - @code inline void fatal_condition (bool condition, char const* category); @endcode -*/ -#define fatal_condition(condition,category) static_cast \ - (((!!(condition)) || (reportFatalError ( \ - category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), 0))) - -/** Replacement for assert which generates a fatal error if the condition is false. - The condition is always evaluated regardless of compilation settings. - Meets this declaration syntax: - @code inline void fatal_assert (bool condition); @endcode -*/ -#define fatal_assert(condition) fatal_condition(condition,"Assertion") - -/** Reports a fatal error message type if the condition is false - The condition is always evaluated regardless of settings. - Meets this declaration syntax: - @code inline void fatal_condition (bool condition, char const* category); @endcode -*/ -#define meets_condition(condition,category) static_cast \ - (((!!(condition)) || (reportFatalError ( \ - category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), false))) - -/** Condition tests for programming by contract. - The condition is always evaluated regardless of settings, and gets returned. - Meets this declaration syntax: - @code inline bool meets_condition (bool); @endcode -*/ -/** @{ */ -#define meets_precondition(condition) meets_condition(condition,"Pre-condition") -#define meets_postcondition(condition) meets_condition(condition,"Post-condition") -#define meets_invariant(condition) meets_condition(condition,"Invariant") -/** @} */ - -/** Condition tests for programming by contract. - The condition is evaluated only if BEAST_DISABLE_CONTRACT_CHECKS is 0. - Meets this declaration syntax: - @code inline void check_condition (bool); @endcode - @see BEAST_DISABLE_CONTRACT_CHECKS -*/ -/** @{ */ -#if ! BEAST_DISABLE_CONTRACT_CHECKS -# define check_precondition(condition) meets_precondition(condition) -# define check_postcondition(condition) meets_postcondition(condition) -# define check_invariant(condition) meets_invariant(condition) -#else -# define check_precondition(condition) ((void)0) -# define check_postcondition(condition) ((void)0) -# define check_invariant(condition) ((void)0) -#endif -/** @} */ +extern void reportFatalError (char const* message, char const* fileName, int lineNumber); #endif diff --git a/Subtrees/beast/modules/beast_core/system/PlatformDefs.h b/Subtrees/beast/modules/beast_core/system/PlatformDefs.h index 619c219577..11ac689f32 100644 --- a/Subtrees/beast/modules/beast_core/system/PlatformDefs.h +++ b/Subtrees/beast/modules/beast_core/system/PlatformDefs.h @@ -107,7 +107,11 @@ correct behaviour of your program! @see bassertfalse */ +#if 0 #define bassert(expression) { if (! (expression)) bassertfalse; } +#else +#define bassert(expression) { if (! (expression)) fatal_error(#expression); } +#endif #else diff --git a/Subtrees/beast/modules/beast_core/thread/beast_InterruptibleThread.cpp b/Subtrees/beast/modules/beast_core/thread/beast_InterruptibleThread.cpp index 1e7fb08aee..e732b3cba3 100644 --- a/Subtrees/beast/modules/beast_core/thread/beast_InterruptibleThread.cpp +++ b/Subtrees/beast/modules/beast_core/thread/beast_InterruptibleThread.cpp @@ -97,12 +97,16 @@ bool InterruptibleThread::wait (int milliSeconds) } } - if (!interrupted) + if (! interrupted) { + bassert (m_state == stateWait); + interrupted = m_thread.wait (milliSeconds); - if (!interrupted) + if (! interrupted) { + // The wait timed out + // if (m_state.tryChangeState (stateWait, stateRun)) { interrupted = false; @@ -114,6 +118,13 @@ bool InterruptibleThread::wait (int milliSeconds) interrupted = true; } } + else + { + // The event became signalled, which can only + // happen via m_event.notify() in interrupt() + // + bassert (m_state == stateRun); + } } return interrupted;