From 3184433756c6014e5192bdb92df9a233c62b55e7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 13 Mar 2016 18:12:33 +0100 Subject: Moved NetworkInterfaceEnum test to a separate test project. --- src/OSSupport/NetworkInterfaceEnum.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'src') diff --git a/src/OSSupport/NetworkInterfaceEnum.cpp b/src/OSSupport/NetworkInterfaceEnum.cpp index d74565e07..c7339c408 100644 --- a/src/OSSupport/NetworkInterfaceEnum.cpp +++ b/src/OSSupport/NetworkInterfaceEnum.cpp @@ -22,34 +22,6 @@ -#ifdef SELF_TEST - -static class cEnumIPAddressTest -{ -public: - cEnumIPAddressTest(void) - { - cSelfTests::Get().Register(std::function(&Test), "Network IP enumeration"); - } - - static void Test(void) - { - LOG("Enumerating all IP addresses..."); - auto IPs = cNetwork::EnumLocalIPAddresses(); - for (auto & ip: IPs) - { - LOG(" %s", ip.c_str()); - } - LOG("Done."); - } -} g_EnumIPAddressTest; - -#endif // SELF_TEST - - - - - #ifdef _WIN32 /** Converts the SOCKET_ADDRESS structure received from the OS into an IP address string. */ -- cgit v1.2.3 From ab6f68b42cac83e4f8fdc93e9654eb536f7f2e32 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 13 Mar 2016 18:59:42 +0100 Subject: SelfTests: Moved ByteBuffer test to a separate project. --- src/ByteBuffer.cpp | 66 ------------------------------------------------------ 1 file changed, 66 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 16620becd..230a5ffbb 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -8,7 +8,6 @@ #include "ByteBuffer.h" #include "Endianness.h" #include "OSSupport/IsThread.h" -#include "SelfTests.h" @@ -54,71 +53,6 @@ Unfortunately it is very slow, so it is disabled even for regular DEBUG builds. -#ifdef SELF_TEST - -/** Self-test of the VarInt-reading and writing code */ -static class cByteBufferSelfTest -{ -public: - cByteBufferSelfTest(void) - { - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestRead), "ByteBuffer read"); - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrite), "ByteBuffer write"); - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrap), "ByteBuffer wraparound"); - } - - static void TestRead(void) - { - cByteBuffer buf(50); - buf.Write("\x05\xac\x02\x00", 4); - UInt32 v1; - assert_test(buf.ReadVarInt(v1) && (v1 == 5)); - UInt32 v2; - assert_test(buf.ReadVarInt(v2) && (v2 == 300)); - UInt32 v3; - assert_test(buf.ReadVarInt(v3) && (v3 == 0)); - } - - static void TestWrite(void) - { - cByteBuffer buf(50); - buf.WriteVarInt32(5); - buf.WriteVarInt32(300); - buf.WriteVarInt32(0); - AString All; - buf.ReadAll(All); - assert_test(All.size() == 4); - assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0); - } - - static void TestWrap(void) - { - cByteBuffer buf(3); - for (int i = 0; i < 1000; i++) - { - size_t FreeSpace = buf.GetFreeSpace(); - assert_test(buf.GetReadableSpace() == 0); - assert_test(FreeSpace > 0); - assert_test(buf.Write("a", 1)); - assert_test(buf.CanReadBytes(1)); - assert_test(buf.GetReadableSpace() == 1); - UInt8 v = 0; - assert_test(buf.ReadBEUInt8(v)); - assert_test(v == 'a'); - assert_test(buf.GetReadableSpace() == 0); - buf.CommitRead(); - assert_test(buf.GetFreeSpace() == FreeSpace); // We're back to normal - } - } - -} g_ByteBufferTest; - -#endif - - - - - #ifdef DEBUG_SINGLE_THREAD_ACCESS /** Simple RAII class that is used for checking that no two threads are using an object simultanously. -- cgit v1.2.3 From db17f585afc283a107b8fbec078e1d2d674e52b0 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 13 Mar 2016 19:34:56 +0100 Subject: SelfTests: Moved cCompositeChat test to a separate project. --- src/CompositeChat.cpp | 89 --------------------------------------------------- 1 file changed, 89 deletions(-) (limited to 'src') diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 82e3d09f2..d110d5908 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -6,95 +6,6 @@ #include "Globals.h" #include "CompositeChat.h" #include "ClientHandle.h" -#include "SelfTests.h" - - - - - -#ifdef SELF_TEST - -/** A simple self-test that verifies that the composite chat parser is working properly. */ -class SelfTest_CompositeChat -{ -public: - SelfTest_CompositeChat(void) - { - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser1), "CompositeChat parser test 1"); - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser2), "CompositeChat parser test 2"); - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser3), "CompositeChat parser test 3"); - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser4), "CompositeChat parser test 4"); - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser5), "CompositeChat parser test 5"); - } - - static void TestParser1(void) - { - cCompositeChat Msg; - Msg.ParseText("Testing @2color codes and http://links parser"); - const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert_test(Parts.size() == 4); - assert_test(Parts[0]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[1]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl); - assert_test(Parts[3]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[0]->m_Style == ""); - assert_test(Parts[1]->m_Style == "@2"); - assert_test(Parts[2]->m_Style == "@2"); - assert_test(Parts[3]->m_Style == "@2"); - } - - static void TestParser2(void) - { - cCompositeChat Msg; - Msg.ParseText("@3Advanced stuff: @5overriding color codes and http://links.with/@4color-in-them handling"); - const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert_test(Parts.size() == 4); - assert_test(Parts[0]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[1]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl); - assert_test(Parts[3]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[0]->m_Style == "@3"); - assert_test(Parts[1]->m_Style == "@5"); - assert_test(Parts[2]->m_Style == "@5"); - assert_test(Parts[3]->m_Style == "@5"); - } - - static void TestParser3(void) - { - cCompositeChat Msg; - Msg.ParseText("http://links.starting the text"); - const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert_test(Parts.size() == 2); - assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl); - assert_test(Parts[1]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[0]->m_Style == ""); - assert_test(Parts[1]->m_Style == ""); - } - - static void TestParser4(void) - { - cCompositeChat Msg; - Msg.ParseText("links finishing the text: http://some.server"); - const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert_test(Parts.size() == 2); - assert_test(Parts[0]->m_PartType == cCompositeChat::ptText); - assert_test(Parts[1]->m_PartType == cCompositeChat::ptUrl); - assert_test(Parts[0]->m_Style == ""); - assert_test(Parts[1]->m_Style == ""); - } - - static void TestParser5(void) - { - cCompositeChat Msg; - Msg.ParseText("http://only.links"); - const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert_test(Parts.size() == 1); - assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl); - assert_test(Parts[0]->m_Style == ""); - } - -} gTest; -#endif // SELF_TEST -- cgit v1.2.3 From a781be545611ac6dd4aa61433b77fbe4f2aeddad Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 13 Mar 2016 19:13:17 +0100 Subject: SelfTests: Moved SchematicFileSerializer test into a separate project. --- src/WorldStorage/SchematicFileSerializer.cpp | 36 ---------------------------- 1 file changed, 36 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index 1b2047574..3fc36e86c 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -9,42 +9,6 @@ #include "FastNBT.h" #include "SchematicFileSerializer.h" #include "../StringCompression.h" -#include "../SelfTests.h" - - - - - -#ifdef SELF_TEST - -static class cSchematicStringSelfTest -{ -public: - cSchematicStringSelfTest(void) - { - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&Test), "Schematic-to-string serialization"); - } - - static void Test(void) - { - cBlockArea ba; - ba.Create(21, 256, 21); - ba.RelLine(0, 0, 0, 9, 8, 7, cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_WOODEN_STAIRS, 1); - AString Schematic; - if (!cSchematicFileSerializer::SaveToSchematicString(ba, Schematic)) - { - assert_test(!"Schematic failed to save!"); - } - cBlockArea ba2; - if (!cSchematicFileSerializer::LoadFromSchematicString(ba2, Schematic)) - { - assert_test(!"Schematic failed to load!"); - } - } -} g_SelfTest; - -#endif - -- cgit v1.2.3 From 75a81cf75310fd6b9d8510acc3add59d41f0732a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 13 Mar 2016 19:25:37 +0100 Subject: SelfTests: Moved BoundingBox test to a separate project. --- src/BoundingBox.cpp | 66 ----------------------------------------------------- 1 file changed, 66 deletions(-) (limited to 'src') diff --git a/src/BoundingBox.cpp b/src/BoundingBox.cpp index bd236bbd7..ecf810fa8 100644 --- a/src/BoundingBox.cpp +++ b/src/BoundingBox.cpp @@ -5,72 +5,6 @@ #include "Globals.h" #include "BoundingBox.h" #include "Defines.h" -#include "SelfTests.h" - - - - - -#ifdef SELF_TEST - -/** A simple self-test that is executed on program start, used to verify bbox functionality */ -static class SelfTest_BoundingBox -{ -public: - SelfTest_BoundingBox(void) - { - cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&Test), "Bounding box intersections"); - } - - static void Test(void) - { - Vector3d Min(1, 1, 1); - Vector3d Max(2, 2, 2); - Vector3d LineDefs[] = - { - Vector3d(1.5, 4, 1.5), Vector3d(1.5, 3, 1.5), // Should intersect at 2, face 1 (YP) - Vector3d(1.5, 0, 1.5), Vector3d(1.5, 4, 1.5), // Should intersect at 0.25, face 0 (YM) - Vector3d(0, 0, 0), Vector3d(2, 2, 2), // Should intersect at 0.5, face 0, 3 or 5 (anyM) - Vector3d(0.999, 0, 1.5), Vector3d(0.999, 4, 1.5), // Should not intersect - Vector3d(1.999, 0, 1.5), Vector3d(1.999, 4, 1.5), // Should intersect at 0.25, face 0 (YM) - Vector3d(2.001, 0, 1.5), Vector3d(2.001, 4, 1.5), // Should not intersect - } ; - bool Results[] = {true, true, true, false, true, false}; - double LineCoeffs[] = {2, 0.25, 0.5, 0, 0.25, 0}; - - for (size_t i = 0; i < ARRAYCOUNT(LineDefs) / 2; i++) - { - double LineCoeff; - eBlockFace Face; - Vector3d Line1 = LineDefs[2 * i]; - Vector3d Line2 = LineDefs[2 * i + 1]; - bool res = cBoundingBox::CalcLineIntersection(Min, Max, Line1, Line2, LineCoeff, Face); - if (res != Results[i]) - { - LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d", - Line1.x, Line1.y, Line1.z, - Line2.x, Line2.y, Line2.z, - res ? 1 : 0, LineCoeff, Face - ); - abort(); - } - if (res) - { - if (LineCoeff != LineCoeffs[i]) - { - LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d", - Line1.x, Line1.y, Line1.z, - Line2.x, Line2.y, Line2.z, - res ? 1 : 0, LineCoeff, Face - ); - abort(); - } - } - } // for i - LineDefs[] - } -} g_BoundingBoxTest; - -#endif -- cgit v1.2.3 From 36eefbf0f25c93ed30bcff9d7abbb8b8696964df Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 10 Jun 2016 20:18:49 +0200 Subject: SelfTests: Removed the unneeded cSelfTests class. --- src/CMakeLists.txt | 2 - src/Generating/PieceGenerator.cpp | 1 - src/Generating/PrefabPiecePool.cpp | 1 - src/OSSupport/NetworkInterfaceEnum.cpp | 1 - src/Root.cpp | 6 --- src/SelfTests.cpp | 71 ---------------------------------- src/SelfTests.h | 51 ------------------------ 7 files changed, 133 deletions(-) delete mode 100644 src/SelfTests.cpp delete mode 100644 src/SelfTests.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5c57be1c9..76a18801d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,7 +63,6 @@ SET (SRCS RCONServer.cpp Root.cpp Scoreboard.cpp - SelfTests.cpp Server.cpp SetChunkData.cpp SpawnPrepare.cpp @@ -140,7 +139,6 @@ SET (HDRS RCONServer.h Root.h Scoreboard.h - SelfTests.h Server.h SetChunkData.h SettingsRepositoryInterface.h diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index d6204ce85..842ac349b 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -6,7 +6,6 @@ #include "Globals.h" #include "PieceGenerator.h" -#include "../SelfTests.h" #include "VerticalStrategy.h" #include "VerticalLimit.h" diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp index e1bb9f684..417f8ce7e 100644 --- a/src/Generating/PrefabPiecePool.cpp +++ b/src/Generating/PrefabPiecePool.cpp @@ -6,7 +6,6 @@ #include "Globals.h" #include "PrefabPiecePool.h" #include "../Bindings/LuaState.h" -#include "SelfTests.h" #include "WorldStorage/SchematicFileSerializer.h" #include "VerticalStrategy.h" #include "../StringCompression.h" diff --git a/src/OSSupport/NetworkInterfaceEnum.cpp b/src/OSSupport/NetworkInterfaceEnum.cpp index c7339c408..d3a254c23 100644 --- a/src/OSSupport/NetworkInterfaceEnum.cpp +++ b/src/OSSupport/NetworkInterfaceEnum.cpp @@ -6,7 +6,6 @@ #include "Globals.h" #include "Network.h" #include "event2/util.h" -#include "../SelfTests.h" #ifdef _WIN32 #include diff --git a/src/Root.cpp b/src/Root.cpp index bd8e026f3..1eca73cb2 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -22,7 +22,6 @@ #include "IniFile.h" #include "SettingsRepositoryInterface.h" #include "OverridesSettingsRepository.h" -#include "SelfTests.h" #include "Logger.h" #include @@ -128,11 +127,6 @@ void cRoot::Start(std::unique_ptr a_OverridesRepo) LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); #endif - // Run the self-tests registered previously via cSelfTests::Register(): - #ifdef SELF_TEST - cSelfTests::ExecuteAll(); - #endif - cDeadlockDetect dd; auto BeginTime = std::chrono::steady_clock::now(); diff --git a/src/SelfTests.cpp b/src/SelfTests.cpp deleted file mode 100644 index 7e35e675e..000000000 --- a/src/SelfTests.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -// SelfTests.h - -// Implements the cSelfTests class representing the singleton used for registering self-tests -// This class is only declared if SELF_TEST macro is defined. - -#include "Globals.h" -#include "SelfTests.h" - - - - - -#ifdef SELF_TEST - cSelfTests::cSelfTests(void): - m_AllowRegistering(true) - { - } - - - - - - cSelfTests & cSelfTests::Get(void) - { - static cSelfTests singleton; - return singleton; - } - - - - - - void cSelfTests::Register(cSelfTests::SelfTestFunction a_FnToExecute, const AString & a_TestName) - { - ASSERT(Get().m_AllowRegistering); - Get().m_SelfTests.push_back(std::make_pair(a_FnToExecute, a_TestName)); - } - - - - - - void cSelfTests::ExecuteAll(void) - { - Get().m_AllowRegistering = false; - LOG("--- Performing self-tests ---"); - for (auto & test: Get().m_SelfTests) - { - LOG("Performing self-test: %s", test.second.c_str()); - try - { - test.first(); - } - catch (const std::exception & exc) - { - LOGWARNING("Exception in test %s: %s", test.second.c_str(), exc.what()); - } - catch (...) - { - LOGWARNING("Unknown exception in test %s", test.second.c_str()); - } - } // for test - m_SelfTests[] - LOG("--- Self-tests finished ---"); - } - -#endif // SELF_TEST - - - - diff --git a/src/SelfTests.h b/src/SelfTests.h deleted file mode 100644 index 03a3b5faa..000000000 --- a/src/SelfTests.h +++ /dev/null @@ -1,51 +0,0 @@ - -// SelfTests.h - -// Declares the cSelfTests class representing the singleton used for registering self-tests -// This class is only declared if SELF_TEST macro is defined. - - - - - -#pragma once - - - - - -#ifdef SELF_TEST - /** Singleton containing registered self-tests. - Used to schedule self-tests to run after the logging framework is initialized (#2228). */ - class cSelfTests - { - public: - /** Returns the singleton instance of this class. */ - static cSelfTests & Get(void); - - // typedef void (* SelfTestFunction)(void); - typedef std::function SelfTestFunction; - - /** Registers a self-test to be executed once the logging framework is initialized. */ - static void Register(SelfTestFunction a_FnToExecute, const AString & a_TestName); - - /** Executes all the registered self-tests. */ - static void ExecuteAll(void); - - protected: - typedef std::vector> SelfTestFunctions; - - /** Functions (registered self-tests) to call once the logging framework is initialized. */ - SelfTestFunctions m_SelfTests; - - /** If true, tests may be registered. Set to false once the tests are executed, to detect tests that are registered too late. */ - bool m_AllowRegistering; - - - cSelfTests(void); - }; -#endif // SELF_TEST - - - - -- cgit v1.2.3 From 96034810dfae37ec0b489ae5d3feb5b756e34e67 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 17 Jun 2016 13:43:58 +0200 Subject: Flush immediately after each line when running tests. --- src/Globals.h | 109 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 55 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/Globals.h b/src/Globals.h index dd331cd34..25d2f740e 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -255,72 +255,73 @@ template class SizeChecker; #ifndef TEST_GLOBALS -// These fiunctions are defined in Logger.cpp, but are declared here to avoid including all of logger.h -extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2); -extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2); -extern void LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2); -extern void LOGERROR (const char * a_Format, ...) FORMATSTRING(1, 2); - - - - + // These functions are defined in Logger.cpp, but are declared here to avoid including all of logger.h + extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2); + extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2); + extern void LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2); + extern void LOGERROR (const char * a_Format, ...) FORMATSTRING(1, 2); + + // In debug builds, translate LOGD to LOG, otherwise leave it out altogether: + #ifdef _DEBUG + #define LOGD LOG + #else + #define LOGD(...) + #endif // _DEBUG -// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: -#ifdef _DEBUG - #define LOGD LOG -#else - #define LOGD(...) -#endif // _DEBUG + #define LOGWARN LOGWARNING -#define LOGWARN LOGWARNING #else // Logging functions -void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2); + void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2); -void inline LOGERROR(const char * a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - vprintf(a_Format, argList); - putchar('\n'); - va_end(argList); -} + void inline LOGERROR(const char * a_Format, ...) + { + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + putchar('\n'); + fflush(stdout); + va_end(argList); + } -void inline LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2); + void inline LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2); -void inline LOGWARNING(const char * a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - vprintf(a_Format, argList); - putchar('\n'); - va_end(argList); -} + void inline LOGWARNING(const char * a_Format, ...) + { + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + putchar('\n'); + fflush(stdout); + va_end(argList); + } -void inline LOGD(const char * a_Format, ...) FORMATSTRING(1, 2); + void inline LOGD(const char * a_Format, ...) FORMATSTRING(1, 2); -void inline LOGD(const char * a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - vprintf(a_Format, argList); - putchar('\n'); - va_end(argList); -} + void inline LOGD(const char * a_Format, ...) + { + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + putchar('\n'); + fflush(stdout); + va_end(argList); + } -void inline LOG(const char * a_Format, ...) FORMATSTRING(1, 2); + void inline LOG(const char * a_Format, ...) FORMATSTRING(1, 2); -void inline LOG(const char * a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - vprintf(a_Format, argList); - putchar('\n'); - va_end(argList); -} + void inline LOG(const char * a_Format, ...) + { + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + putchar('\n'); + fflush(stdout); + va_end(argList); + } -#define LOGINFO LOG -#define LOGWARN LOGWARNING + #define LOGINFO LOG + #define LOGWARN LOGWARNING #endif -- cgit v1.2.3 From 8610083a8e8ad66806c66d0199d0d8a900ceb358 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 17 Jun 2016 16:25:31 +0200 Subject: cNetwork: Fixed possible hang when terminating immediately after init. --- src/OSSupport/NetworkSingleton.cpp | 21 +++++++++++++++++++-- src/OSSupport/NetworkSingleton.h | 8 ++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/OSSupport/NetworkSingleton.cpp b/src/OSSupport/NetworkSingleton.cpp index c16f92c5a..d0abafcbd 100644 --- a/src/OSSupport/NetworkSingleton.cpp +++ b/src/OSSupport/NetworkSingleton.cpp @@ -6,7 +6,6 @@ #include "Globals.h" #include "NetworkSingleton.h" -#include #include #include #include @@ -91,8 +90,11 @@ void cNetworkSingleton::Initialise(void) } // Create the event loop thread: - m_EventLoopThread = std::thread(RunEventLoop, this); m_HasTerminated = false; + m_StartupEvent.reset(new cEvent); + m_EventLoopThread = std::thread(RunEventLoop, this); + m_StartupEvent->Wait(); // Wait for the LibEvent loop to actually start running (otherwise calling Terminate too soon would hang, see #3228) + m_StartupEvent.reset(); // Don't need the cEvent any more, release all its resources } @@ -153,6 +155,9 @@ void cNetworkSingleton::LogCallback(int a_Severity, const char * a_Msg) void cNetworkSingleton::RunEventLoop(cNetworkSingleton * a_Self) { + auto timer = evtimer_new(a_Self->m_EventBase, SignalizeStartup, a_Self); + timeval timeout{}; // Zero timeout - execute immediately + evtimer_add(timer, &timeout); event_base_loop(a_Self->m_EventBase, EVLOOP_NO_EXIT_ON_EMPTY); } @@ -160,6 +165,18 @@ void cNetworkSingleton::RunEventLoop(cNetworkSingleton * a_Self) +void cNetworkSingleton::SignalizeStartup(evutil_socket_t a_Socket, short a_Events, void * a_Self) +{ + auto self = reinterpret_cast(a_Self); + ASSERT(self != nullptr); + ASSERT(self->m_StartupEvent != nullptr); + self->m_StartupEvent->Set(); +} + + + + + void cNetworkSingleton::AddHostnameLookup(cHostnameLookupPtr a_HostnameLookup) { ASSERT(!m_HasTerminated); diff --git a/src/OSSupport/NetworkSingleton.h b/src/OSSupport/NetworkSingleton.h index c72df38ec..75713d261 100644 --- a/src/OSSupport/NetworkSingleton.h +++ b/src/OSSupport/NetworkSingleton.h @@ -13,6 +13,7 @@ #pragma once +#include #include "Network.h" #include "CriticalSection.h" #include "Event.h" @@ -127,11 +128,18 @@ protected: /** The thread in which the main LibEvent loop runs. */ std::thread m_EventLoopThread; + /** Event that is signalled once the startup is finished and the LibEvent loop is running. */ + UniquePtr m_StartupEvent; + + /** Converts LibEvent-generated log events into log messages in MCS log. */ static void LogCallback(int a_Severity, const char * a_Msg); /** Implements the thread that runs LibEvent's event dispatcher loop. */ static void RunEventLoop(cNetworkSingleton * a_Self); + + /** Callback called by LibEvent when the event loop is started. */ + static void SignalizeStartup(evutil_socket_t a_Socket, short a_Events, void * a_Self); }; -- cgit v1.2.3