1
0
Fork 0

Fix Windows XP to 7 compatibility (#5167)

* Partially reverts 01a4e696b
* Unify thread names
- Remove use of GetThreadId API
This commit is contained in:
Tiger Wang 2021-03-28 13:34:57 +01:00 committed by GitHub
parent 58d7b7e5c7
commit 5123850db0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 60 additions and 71 deletions

View File

@ -126,7 +126,7 @@ AString cMCADefrag::GetNextFileName(void)
// cMCADefrag::cThread:
cMCADefrag::cThread::cThread(cMCADefrag & a_Parent) :
super("MCADefrag thread"),
super("MCA Defragmentor"),
m_Parent(a_Parent),
m_IsChunkUncompressed(false),
m_Compressor(12) // Set the highest compression factor

View File

@ -18,7 +18,7 @@ const size_t QUEUE_SKIP_LIMIT = 500;
cChunkGeneratorThread::cChunkGeneratorThread(void) :
Super("cChunkGeneratorThread"),
Super("Chunk Generator"),
m_Generator(nullptr),
m_PluginInterface(nullptr),
m_ChunkSink(nullptr)

View File

@ -59,7 +59,7 @@ public:
// cChunkSender:
cChunkSender::cChunkSender(cWorld & a_World) :
Super("ChunkSender"),
Super("Chunk Sender"),
m_World(a_World),
m_Serializer(m_World.GetDimension())
{

View File

@ -21,7 +21,7 @@ const int CYCLE_MILLISECONDS = 100;
cDeadlockDetect::cDeadlockDetect(void) :
Super("DeadlockDetect"),
Super("Deadlock Detector"),
m_IntervalSec(1000)
{
}

View File

@ -78,22 +78,24 @@
// OS-dependent stuff:
#ifdef _WIN32
#define NOMINMAX // Windows SDK defines min and max macros, messing up with our std::min and std::max usage.
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT _WIN32_WINNT_WS03 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher
#define _WIN32_WINNT 0x0501 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher.
// Windows SDK defines min and max macros, messing up with our std::min and std::max usage
#define NOMINMAX
// Use CryptoAPI primitives when targeting a version that supports encrypting with AES-CFB8 smaller than a full block at a time.
#define PLATFORM_CRYPTOGRAPHY (_WIN32_WINNT >= 0x0602)
#include <Windows.h>
#include <winsock2.h>
#include <Ws2tcpip.h> // IPv6 stuff
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant:
#ifdef GetFreeSpace
#undef GetFreeSpace
#endif // GetFreeSpace
#else
#define PLATFORM_CRYPTOGRAPHY 0
#include <arpa/inet.h>
#include <unistd.h>
#endif

View File

@ -100,7 +100,7 @@ public:
// cLightingThread:
cLightingThread::cLightingThread(cWorld & a_World):
Super("cLightingThread"),
Super("Lighting Executor"),
m_World(a_World),
m_MaxHeight(0),
m_NumSeeds(0)

View File

@ -2,7 +2,6 @@
// IsThread.cpp
// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread.
// This class will eventually suupersede the old cThread class
#include "Globals.h"
#include "IsThread.h"
@ -11,46 +10,12 @@
#if defined(_MSC_VER) && !defined(NDEBUG)
// Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
struct THREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1 = caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
};
#pragma pack(pop)
/** Sets the name of a thread with the specified ID
(When in MSVC, the debugger provides "thread naming" by catching special exceptions)
*/
static void SetThreadName(std::thread * a_Thread, const char * a_ThreadName)
{
THREADNAME_INFO info { 0x1000, a_ThreadName, GetThreadId(a_Thread->native_handle()), 0 };
__try
{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
#endif // _MSC_VER && !NDEBUG
////////////////////////////////////////////////////////////////////////////////
// cIsThread:
cIsThread::cIsThread(const AString & a_ThreadName) :
cIsThread::cIsThread(AString && a_ThreadName) :
m_ShouldTerminate(false),
m_ThreadName(a_ThreadName)
m_ThreadName(std::move(a_ThreadName))
{
}
@ -69,6 +34,36 @@ cIsThread::~cIsThread()
void cIsThread::DoExecute(void)
{
#if defined(_MSC_VER) && !defined(NDEBUG)
/* Sets the name of this thread.
(When in MSVC, the debugger provides "thread naming" by catching special exceptions)
Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */
#pragma pack(push, 8)
struct THREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1 = caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
};
#pragma pack(pop)
if (!m_ThreadName.empty())
{
const DWORD NAME_EXCEPTION = 0x406D1388;
const THREADNAME_INFO Name = { 0x1000, m_ThreadName.c_str(), -1, 0 };
__try
{
RaiseException(NAME_EXCEPTION, 0, sizeof(Name) / sizeof(ULONG_PTR), reinterpret_cast<const ULONG_PTR *>(&Name));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
#endif
m_evtStart.Wait();
Execute();
}
@ -84,13 +79,6 @@ bool cIsThread::Start(void)
// Initialize the thread:
m_Thread = std::thread(&cIsThread::DoExecute, this);
#if defined(_MSC_VER) && !defined(NDEBUG)
if (!m_ThreadName.empty())
{
SetThreadName(&m_Thread, m_ThreadName.c_str());
}
#endif
// Notify the thread that initialization is complete and it can run its code safely:
m_evtStart.Set();
@ -120,7 +108,7 @@ void cIsThread::Stop(void)
bool cIsThread::Wait(void)
{
LOGD("Waiting for thread %s to finish", m_ThreadName.c_str());
LOGD("Waiting for the %s thread to finish", m_ThreadName.c_str());
if (m_Thread.joinable())
{
try
@ -130,11 +118,11 @@ bool cIsThread::Wait(void)
}
catch (const std::system_error & a_Exception)
{
LOGERROR("%s error %i: could not join thread %s; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str());
LOGERROR("%s error %i: could not join the %s thread; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str());
return false;
}
}
LOGD("Thread %s finished", m_ThreadName.c_str());
LOGD("The %s thread finished", m_ThreadName.c_str());
return true;
}

View File

@ -32,7 +32,7 @@ protected:
std::atomic<bool> m_ShouldTerminate;
public:
cIsThread(const AString & a_ThreadName);
cIsThread(AString && a_ThreadName);
virtual ~cIsThread();
/** Starts the thread; returns without waiting for the actual start. */

View File

@ -11,7 +11,7 @@
cNetworkLookup::cNetworkLookup() :
cIsThread("NetworkLookup")
cIsThread("Network Lookup Executor")
{
}

View File

@ -26,7 +26,7 @@
cAuthenticator::cAuthenticator(void) :
Super("cAuthenticator"),
Super("Authenticator"),
m_Server(DEFAULT_AUTH_SERVER),
m_Address(DEFAULT_AUTH_ADDRESS),
m_ShouldAuthenticate(true)

View File

@ -237,7 +237,7 @@ class cMojangAPI::cUpdateThread:
public:
cUpdateThread(cMojangAPI & a_MojangAPI):
Super("cMojangAPI::cUpdateThread"),
Super("MojangAPI Updater"),
m_MojangAPI(a_MojangAPI)
{
}

View File

@ -1046,7 +1046,6 @@ void cRoot::TransitionNextState(NextState a_NextState)
s_StopEvent.Set();
#ifdef WIN32
DWORD Length;
INPUT_RECORD Record
{

View File

@ -71,7 +71,7 @@ public:
// cServer::cTickThread:
cServer::cTickThread::cTickThread(cServer & a_Server) :
Super("ServerTickThread"),
Super("Server Ticker"),
m_Server(a_Server)
{
}

View File

@ -96,7 +96,7 @@ cWorld::cLock::cLock(const cWorld & a_World) :
// cWorld::cTickThread:
cWorld::cTickThread::cTickThread(cWorld & a_World) :
Super(Printf("WorldTickThread: %s", a_World.GetName().c_str())),
Super(Printf("World Ticker (%s)", a_World.GetName().c_str())),
m_World(a_World)
{
}

View File

@ -38,7 +38,7 @@ protected:
// cWorldStorage:
cWorldStorage::cWorldStorage(void) :
Super("cWorldStorage"),
Super("World Storage Executor"),
m_World(nullptr),
m_SaveSchema(nullptr)
{

View File

@ -13,7 +13,7 @@
cAesCfb128Decryptor::cAesCfb128Decryptor(void) :
m_IsValid(false)
{
#ifdef _WIN32
#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
if (!CryptAcquireContext(&m_Aes, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
{
throw std::system_error(GetLastError(), std::system_category());
@ -30,7 +30,7 @@ cAesCfb128Decryptor::cAesCfb128Decryptor(void) :
cAesCfb128Decryptor::~cAesCfb128Decryptor()
{
// Clear the leftover in-memory data, so that they can't be accessed by a backdoor:
#ifdef _WIN32
#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
CryptReleaseContext(m_Aes, 0);
#else
mbedtls_aes_free(&m_Aes);
@ -45,7 +45,7 @@ void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
{
ASSERT(!IsValid()); // Cannot Init twice
#ifdef _WIN32
#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
struct Key
{
PUBLICKEYSTRUC Header;
@ -77,7 +77,7 @@ void cAesCfb128Decryptor::ProcessData(std::byte * const a_EncryptedIn, const siz
{
ASSERT(IsValid()); // Must Init() first
#ifdef _WIN32
#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
ASSERT(a_Length <= std::numeric_limits<DWORD>::max());
DWORD Length = static_cast<DWORD>(a_Length);

View File

@ -9,7 +9,7 @@
#pragma once
#ifdef _WIN32
#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
#include <wincrypt.h>
#else
#include "mbedtls/aes.h"
@ -38,7 +38,7 @@ public:
protected:
#ifdef _WIN32
#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
HCRYPTPROV m_Aes;
HCRYPTKEY m_Key;
#else