diff options
Diffstat (limited to 'src/server/worldserver/Main.cpp')
-rw-r--r-- | src/server/worldserver/Main.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 418b5de5eb1..888b0ad65d4 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -67,7 +67,7 @@ namespace fs = boost::filesystem; #define _TRINITY_CORE_CONFIG "worldserver.conf" #endif -#define WORLD_SLEEP_CONST 50 +#define WORLD_SLEEP_CONST 1 #ifdef _WIN32 #include "ServiceWin32.h" @@ -81,6 +81,9 @@ char serviceDescription[] = "TrinityCore World of Warcraft emulator world servic * 2 - paused */ int m_ServiceStatus = -1; + +#include <boost/dll/shared_library.hpp> +#include <timeapi.h> #endif class FreezeDetector @@ -135,6 +138,44 @@ extern int main(int argc, char** argv) return WinServiceUninstall() == true ? 0 : 1; else if (configService.compare("run") == 0) WinServiceRun(); + + Optional<UINT> newTimerResolution; + boost::system::error_code dllError; + std::shared_ptr<boost::dll::shared_library> winmm(new boost::dll::shared_library("winmm.dll", dllError, boost::dll::load_mode::search_system_folders), [&](boost::dll::shared_library* lib) + { + try + { + if (newTimerResolution) + lib->get<decltype(timeEndPeriod)>("timeEndPeriod")(*newTimerResolution); + } + catch (std::exception const&) + { + // ignore + } + + delete lib; + }); + + if (winmm->is_loaded()) + { + try + { + auto timeGetDevCapsPtr = winmm->get<decltype(timeGetDevCaps)>("timeGetDevCaps"); + // setup timer resolution + TIMECAPS timeResolutionLimits; + if (timeGetDevCapsPtr(&timeResolutionLimits, sizeof(TIMECAPS)) == TIMERR_NOERROR) + { + auto timeBeginPeriodPtr = winmm->get<decltype(timeBeginPeriod)>("timeBeginPeriod"); + newTimerResolution = std::min(std::max(timeResolutionLimits.wPeriodMin, 1u), timeResolutionLimits.wPeriodMax); + timeBeginPeriodPtr(*newTimerResolution); + } + } + catch (std::exception const& e) + { + printf("Failed to initialize timer resolution: %s\n", e.what()); + } + } + #endif std::string configError; @@ -445,16 +486,16 @@ void WorldUpdateLoop() realCurrTime = getMSTime(); uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime); + if (!diff) + { + // sleep until enough time passes that we can update all timers + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } sWorld->Update(diff); realPrevTime = realCurrTime; - uint32 executionTimeDiff = getMSTimeDiff(realCurrTime, getMSTime()); - - // we know exactly how long it took to update the world, if the update took less than WORLD_SLEEP_CONST, sleep for WORLD_SLEEP_CONST - world update time - if (executionTimeDiff < WORLD_SLEEP_CONST) - std::this_thread::sleep_for(std::chrono::milliseconds(WORLD_SLEEP_CONST - executionTimeDiff)); - #ifdef _WIN32 if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE); |