Fix respawn/spawn timers racing ahead under multi-threading
POSIX clock() sums CPU time across every thread in the process, unlike Windows' clock() which tracks wall-clock milliseconds. With several worker threads running, respawn/spawn/AI timers based on clock() raced far ahead of real elapsed time. Switch spawn-timer bookkeeping to time(NULL)/time_t (seconds) throughout the world server, and add a portable clock() shim in sockets.h (backed by CLOCK_MONOTONIC, millisecond resolution) for remaining call sites so CLOCKS_PER_SEC==1000 still holds like it did on Windows. Also: fix MapDelay/VisualDelay/WorldDelay being passed to usleep() (us) without converting from their configured milliseconds; fix the shutdown timer likewise; stop leaking the temporary actor used to run an NPC's AIP script; fix CleanDrops() skipping the element that shifts into position after an erase. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f626c6b93
commit
725620e23c
8 files changed
+66
-37
No files matched your search
+25
-2
@@ -62,6 +62,29 @@
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef _WIN32
|
||||
// The entire codebase was written against Windows' clock(), which returns a
|
||||
// monotonic MILLISECOND counter (CLOCKS_PER_SEC == 1000) that closely tracks
|
||||
// wall-clock time for a normal single-threaded process. POSIX clock() is
|
||||
// completely different: microsecond resolution (CLOCKS_PER_SEC == 1,000,000)
|
||||
// AND it sums CPU time across every thread in the process. With several
|
||||
// worker threads running, POSIX clock() races far ahead of real elapsed
|
||||
// time, breaking every cooldown/timer/AI-tick comparison in the game logic
|
||||
// (movement, attacks, aggro, respawns, buffs, ...). Redirect clock() to a
|
||||
// real wall-clock millisecond counter so CLOCKS_PER_SEC==1000 holds like it
|
||||
// did on Windows, without having to touch every call site individually.
|
||||
#include <time.h>
|
||||
static inline long __rose_portable_clock()
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (long)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
|
||||
}
|
||||
#undef CLOCKS_PER_SEC
|
||||
#define CLOCKS_PER_SEC 1000
|
||||
#define clock() __rose_portable_clock()
|
||||
#endif
|
||||
#include <map>
|
||||
#include "pthread.h"
|
||||
#include <vector>
|
||||
@@ -78,8 +101,8 @@ typedef char SBYTE;
|
||||
typedef unsigned char BYTE;
|
||||
typedef short SWORD;
|
||||
typedef unsigned short WORD;
|
||||
typedef long SDWORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int SDWORD;
|
||||
typedef unsigned int DWORD;
|
||||
typedef long long SQWORD;
|
||||
typedef unsigned long long QWORD;
|
||||
#ifdef _WIN32
|
||||
|
||||
Reference in new issue
Block a user