add additional logging to save thread, stop winsocknetlayer listning on server shutdown

This commit is contained in:
sylvessa 2026-04-06 21:29:32 -05:00
parent 098582dea8
commit 0ccd327b3f
4 changed files with 59 additions and 20 deletions

View file

@ -119,9 +119,27 @@ bool WinsockNetLayer::Initialize()
return true;
}
void WinsockNetLayer::Shutdown()
void WinsockNetLayer::StopListening()
{
StopAdvertising();
s_active = false;
if (s_listenSocket != INVALID_SOCKET)
{
closesocket(s_listenSocket);
s_listenSocket = INVALID_SOCKET;
}
if (s_acceptThread != nullptr)
{
WaitForSingleObject(s_acceptThread, 2000);
CloseHandle(s_acceptThread);
s_acceptThread = nullptr;
}
}
void WinsockNetLayer::Shutdown()
{
StopListening();
StopDiscovery();
s_joinCancel = true;
@ -133,29 +151,14 @@ void WinsockNetLayer::Shutdown()
}
s_joinState = eJoinState_Idle;
s_active = false;
s_connected = false;
if (s_listenSocket != INVALID_SOCKET)
{
closesocket(s_listenSocket);
s_listenSocket = INVALID_SOCKET;
}
if (s_hostConnectionSocket != INVALID_SOCKET)
{
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
}
// Stop accept loop first so no new RecvThread can be created while shutting down.
if (s_acceptThread != nullptr)
{
WaitForSingleObject(s_acceptThread, 2000);
CloseHandle(s_acceptThread);
s_acceptThread = nullptr;
}
std::vector<HANDLE> recvThreads;
EnterCriticalSection(&s_connectionsLock);
for (size_t i = 0; i < s_connections.size(); i++)

View file

@ -67,6 +67,7 @@ class WinsockNetLayer
public:
static bool Initialize();
static void Shutdown();
static void StopListening();
static bool HostGame(int port, const char* bindIp = nullptr);
static bool JoinGame(const char* ip, int port);

View file

@ -705,6 +705,7 @@ int main(int argc, char **argv)
LogWorldIO("Waiting for autosave to complete...");
}
WinsockNetLayer::StopListening();
MinecraftServer::HaltServer();
if (g_NetworkManager.ServerStoppedValid())
@ -719,9 +720,22 @@ int main(int argc, char **argv)
waitThread.WaitForCompletion(INFINITE);
}
DWORD bgWaitStart = GetTickCount();
DWORD lastHeartbeat = bgWaitStart;
if (ConsoleSaveFileOriginal::hasPendingBackgroundSave())
{
LogInfof("shutdown", "Waiting for background save to complete...");
}
while (ConsoleSaveFileOriginal::hasPendingBackgroundSave())
{
TickCoreSystems();
DWORD now = GetTickCount();
if ((LONG)(now - lastHeartbeat) >= 5000)
{
LogInfof("shutdown", "waiting for background save to complete... (%u sec elapsed)", (now - bgWaitStart) / 1000);
lastHeartbeat = now;
}
Sleep(10);
}

View file

@ -731,20 +731,37 @@ void ConsoleSaveFileOriginal::Flush(bool autosave, bool updateThumbnail )
s_bgSaveActive.store(true, std::memory_order_release);
std::thread([snap, fileSize, thumb, thumbSz, meta, metaLen, this]() {
app.DebugPrintf("bg-save: thread started, fileSize=%u (%.1f MB)\n", fileSize, fileSize / (1024.0f * 1024.0f));
unsigned int compLen = fileSize + 8;
app.DebugPrintf("bg-save: AllocateSaveData(%u) attempt 1\n", compLen);
byte *buf = static_cast<byte *>(StorageManager.AllocateSaveData(compLen));
if (!buf)
{
// FAIL!! attempt precalc
app.DebugPrintf("bg-save: first alloc failed, computing compressed size...\n");
compLen = 0;
LARGE_INTEGER pcFreq, pcStart, pcEnd;
QueryPerformanceFrequency(&pcFreq);
QueryPerformanceCounter(&pcStart);
Compression::getCompression()->Compress(nullptr, &compLen, snap, fileSize);
QueryPerformanceCounter(&pcEnd);
float precalcSec = (float)(pcEnd.QuadPart - pcStart.QuadPart) / (float)pcFreq.QuadPart;
compLen += 8;
app.DebugPrintf("bg-save: precalc done in %.3f sec, compressed size=%u (%.1f MB)\n", precalcSec, compLen, compLen / (1024.0f * 1024.0f));
app.DebugPrintf("bg-save: AllocateSaveData(%u) attempt 2\n", compLen);
buf = static_cast<byte *>(StorageManager.AllocateSaveData(compLen));
}
if (buf)
{
// COM,PRESS
app.DebugPrintf("bg-save: compressing %u bytes...\n", fileSize);
LARGE_INTEGER pcFreq, pcStart, pcEnd;
QueryPerformanceFrequency(&pcFreq);
QueryPerformanceCounter(&pcStart);
Compression::getCompression()->Compress(buf + 8, &compLen, snap, fileSize);
QueryPerformanceCounter(&pcEnd);
float compSec = (float)(pcEnd.QuadPart - pcStart.QuadPart) / (float)pcFreq.QuadPart;
app.DebugPrintf("bg-save: compressed %u -> %u bytes (%.1f MB -> %.1f MB) in %.3f sec\n",
fileSize, compLen, fileSize / (1024.0f * 1024.0f), compLen / (1024.0f * 1024.0f), compSec);
ZeroMemory(buf, 8);
memcpy(buf + 4, &fileSize, sizeof(fileSize));
@ -757,13 +774,15 @@ void ConsoleSaveFileOriginal::Flush(bool autosave, bool updateThumbnail )
memcpy(s_bgResult.textMeta, meta, sizeof(meta));
s_bgResult.textMetaBytes = metaLen;
s_bgResult.pending = true;
app.DebugPrintf("bg-save: result stored, pending flush on main thread\n");
}
else
{
app.DebugPrintf("save buf alloc failed\n");
app.DebugPrintf("bg-save: ALLOC FAILED - both attempts failed for %u byte world\n", fileSize);
s_bgSaveActive.store(false, std::memory_order_release);
}
delete[] snap;
app.DebugPrintf("bg-save: snapshot freed, thread exiting\n");
}).detach();
return;
}
@ -936,6 +955,7 @@ int ConsoleSaveFileOriginal::SaveSaveDataCallback(LPVOID lpParam,bool bRes)
ConsoleSaveFile *pClass=static_cast<ConsoleSaveFile *>(lpParam);
#ifdef MINECRAFT_SERVER_BUILD
app.DebugPrintf("bg-save: SaveSaveDataCallback fired, success=%d\n", bRes ? 1 : 0);
s_bgSaveActive.store(false, std::memory_order_release);
#endif
@ -1194,13 +1214,14 @@ void ConsoleSaveFileOriginal::flushPendingBackgroundSave()
if (!s_bgResult.pending)
return;
app.DebugPrintf("bg-save: flushing to StorageManager (thumbSize=%u, metaBytes=%d)\n", s_bgResult.thumbSize, s_bgResult.textMetaBytes);
StorageManager.SetSaveImages(
s_bgResult.thumbData, s_bgResult.thumbSize,
nullptr, 0, s_bgResult.textMeta, s_bgResult.textMetaBytes);
StorageManager.SaveSaveData(&ConsoleSaveFileOriginal::SaveSaveDataCallback, s_bgResult.owner);
s_bgResult.pending = false;
// the actual write isnt done until SaveSaveDataCallback fires
app.DebugPrintf("bg-save: StorageManager.SaveSaveData dispatched, awaiting callback\n");
}
bool ConsoleSaveFileOriginal::hasPendingBackgroundSave()