mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Thread: Fix race condition converting time values to local time
Replace thread-unsafe localtime() http://www.cplusplus.com/reference/ctime/localtime/ with thread-safe portable ACE_OS::localtime_r() . Helgrind log: Possible data race during read of size 4 at 0x6F183C0 by thread #1 Locks held: none at 0x14E72E3: World::InitDailyQuestResetTime() (World.cpp:2772) by 0x14E3A01: World::SetInitialWorldSettings() (World.cpp:1790) by 0x101122A: Master::Run() (Master.cpp:164) by 0x101740C: main (Main.cpp:142) This conflicts with a previous write of size 4 by thread #2 Locks held: none at 0x6C2D3BA: __tzfile_compute (tzfile.c:797) by 0x6C2D036: __tz_convert (tzset.c:627) by 0x164146C: LogMessage::getTimeStr(long) (Appender.cpp:23) by 0x1641550: LogMessage::getTimeStr() (Appender.cpp:31) by 0x1641722: Appender::write(LogMessage&) (Appender.cpp:80) by 0x1633FCE: Logger::write(LogMessage&) (Logger.cpp:83) by 0x16433D8: LogOperation::call() (LogOperation.cpp:29) by 0x16428A4: LogWorker::svc() (LogWorker.cpp:45)
This commit is contained in:
@@ -5236,9 +5236,10 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
time_t curTime = time(NULL);
|
||||
tm* lt = localtime(&curTime);
|
||||
tm lt;
|
||||
ACE_OS::localtime_r(&curTime, <);
|
||||
uint64 basetime(curTime);
|
||||
TC_LOG_INFO(LOG_FILTER_GENERAL, "Returning mails current time: hour: %d, minute: %d, second: %d ", lt->tm_hour, lt->tm_min, lt->tm_sec);
|
||||
TC_LOG_INFO(LOG_FILTER_GENERAL, "Returning mails current time: hour: %d, minute: %d, second: %d ", lt.tm_hour, lt.tm_min, lt.tm_sec);
|
||||
|
||||
// Delete all old mails without item and without body immediately, if starting server
|
||||
if (!serverUp)
|
||||
|
||||
@@ -93,8 +93,9 @@ bool Weather::ReGenerate()
|
||||
//78 days between January 1st and March 20nd; 365/4=91 days by season
|
||||
// season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html
|
||||
time_t gtime = sWorld->GetGameTime();
|
||||
struct tm * ltime = localtime(>ime);
|
||||
uint32 season = ((ltime->tm_yday - 78 + 365)/91)%4;
|
||||
struct tm ltime;
|
||||
ACE_OS::localtime_r(>ime, <ime);
|
||||
uint32 season = ((ltime.tm_yday - 78 + 365)/91)%4;
|
||||
|
||||
static char const* seasonName[WEATHER_SEASONS] = { "spring", "summer", "fall", "winter" };
|
||||
|
||||
|
||||
@@ -1730,7 +1730,9 @@ void World::SetInitialWorldSettings()
|
||||
//mailtimer is increased when updating auctions
|
||||
//one second is 1000 -(tested on win system)
|
||||
/// @todo Get rid of magic numbers
|
||||
mail_timer = ((((localtime(&m_gameTime)->tm_hour + 20) % 24)* HOUR * IN_MILLISECONDS) / m_timers[WUPDATE_AUCTIONS].GetInterval());
|
||||
tm localTm;
|
||||
ACE_OS::localtime_r(&m_gameTime, &localTm);
|
||||
mail_timer = ((((localTm.tm_hour + 20) % 24)* HOUR * IN_MILLISECONDS) / m_timers[WUPDATE_AUCTIONS].GetInterval());
|
||||
//1440
|
||||
mail_timer_expires = ((DAY * IN_MILLISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval()));
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Mail timer set to: " UI64FMTD ", mail return is called every " UI64FMTD " minutes", uint64(mail_timer), uint64(mail_timer_expires));
|
||||
@@ -2769,7 +2771,8 @@ void World::InitDailyQuestResetTime()
|
||||
// client built-in time for reset is 6:00 AM
|
||||
// FIX ME: client not show day start time
|
||||
time_t curTime = time(NULL);
|
||||
tm localTm = *localtime(&curTime);
|
||||
tm localTm;
|
||||
ACE_OS::localtime_r(&curTime, &localTm);
|
||||
localTm.tm_hour = 6;
|
||||
localTm.tm_min = 0;
|
||||
localTm.tm_sec = 0;
|
||||
@@ -2802,7 +2805,8 @@ void World::InitRandomBGResetTime()
|
||||
|
||||
// generate time by config
|
||||
time_t curTime = time(NULL);
|
||||
tm localTm = *localtime(&curTime);
|
||||
tm localTm;
|
||||
ACE_OS::localtime_r(&curTime, &localTm);
|
||||
localTm.tm_hour = getIntConfig(CONFIG_RANDOM_BG_RESET_HOUR);
|
||||
localTm.tm_min = 0;
|
||||
localTm.tm_sec = 0;
|
||||
@@ -2829,7 +2833,8 @@ void World::InitGuildResetTime()
|
||||
|
||||
// generate time by config
|
||||
time_t curTime = time(NULL);
|
||||
tm localTm = *localtime(&curTime);
|
||||
tm localTm;
|
||||
ACE_OS::localtime_r(&curTime, &localTm);
|
||||
localTm.tm_hour = getIntConfig(CONFIG_GUILD_RESET_HOUR);
|
||||
localTm.tm_min = 0;
|
||||
localTm.tm_sec = 0;
|
||||
@@ -2913,7 +2918,8 @@ void World::ResetMonthlyQuests()
|
||||
|
||||
// generate time
|
||||
time_t curTime = time(NULL);
|
||||
tm localTm = *localtime(&curTime);
|
||||
tm localTm;
|
||||
ACE_OS::localtime_r(&curTime, &localTm);
|
||||
|
||||
int month = localTm.tm_mon;
|
||||
int year = localTm.tm_year;
|
||||
|
||||
@@ -436,21 +436,23 @@ public:
|
||||
do
|
||||
{
|
||||
time_t timeBan = time_t(fields2[0].GetUInt32());
|
||||
tm* tmBan = localtime(&timeBan);
|
||||
tm tmBan;
|
||||
ACE_OS::localtime_r(&timeBan, &tmBan);
|
||||
|
||||
if (fields2[0].GetUInt32() == fields2[1].GetUInt32())
|
||||
{
|
||||
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
|
||||
accountName.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min,
|
||||
accountName.c_str(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
|
||||
fields2[2].GetCString(), fields2[3].GetCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t timeUnban = time_t(fields2[1].GetUInt32());
|
||||
tm* tmUnban = localtime(&timeUnban);
|
||||
tm tmUnban;
|
||||
ACE_OS::localtime_r(&timeUnban, &tmUnban);
|
||||
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
|
||||
accountName.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min,
|
||||
tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min,
|
||||
accountName.c_str(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
|
||||
tmUnban.tm_year%100, tmUnban.tm_mon+1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min,
|
||||
fields2[2].GetCString(), fields2[3].GetCString());
|
||||
}
|
||||
}
|
||||
@@ -523,21 +525,23 @@ public:
|
||||
do
|
||||
{
|
||||
time_t timeBan = time_t(banFields[0].GetUInt32());
|
||||
tm* tmBan = localtime(&timeBan);
|
||||
tm tmBan;
|
||||
ACE_OS::localtime_r(&timeBan, &tmBan);
|
||||
|
||||
if (banFields[0].GetUInt32() == banFields[1].GetUInt32())
|
||||
{
|
||||
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
|
||||
char_name.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min,
|
||||
char_name.c_str(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
|
||||
banFields[2].GetCString(), banFields[3].GetCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t timeUnban = time_t(banFields[1].GetUInt32());
|
||||
tm* tmUnban = localtime(&timeUnban);
|
||||
tm tmUnban;
|
||||
ACE_OS::localtime_r(&timeUnban, &tmUnban);
|
||||
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
|
||||
char_name.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min,
|
||||
tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min,
|
||||
char_name.c_str(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
|
||||
tmUnban.tm_year%100, tmUnban.tm_mon+1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min,
|
||||
banFields[2].GetCString(), banFields[3].GetCString());
|
||||
}
|
||||
}
|
||||
@@ -602,20 +606,22 @@ public:
|
||||
handler->SendSysMessage("-------------------------------------------------------------------------------");
|
||||
Field* fields = result->Fetch();
|
||||
time_t timeBan = time_t(fields[1].GetUInt32());
|
||||
tm* tmBan = localtime(&timeBan);
|
||||
tm tmBan;
|
||||
ACE_OS::localtime_r(&timeBan, &tmBan);
|
||||
if (fields[1].GetUInt32() == fields[2].GetUInt32())
|
||||
{
|
||||
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
|
||||
fields[0].GetCString(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min,
|
||||
fields[0].GetCString(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
|
||||
fields[3].GetCString(), fields[4].GetCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t timeUnban = time_t(fields[2].GetUInt32());
|
||||
tm* tmUnban = localtime(&timeUnban);
|
||||
tm tmUnban;
|
||||
ACE_OS::localtime_r(&timeUnban, &tmUnban);
|
||||
handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
|
||||
fields[0].GetCString(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min,
|
||||
tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min,
|
||||
fields[0].GetCString(), tmBan.tm_year%100, tmBan.tm_mon+1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min,
|
||||
tmUnban.tm_year%100, tmUnban.tm_mon+1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min,
|
||||
fields[3].GetCString(), fields[4].GetCString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
#include <ace/Guard_T.h>
|
||||
#include <ace/RW_Thread_Mutex.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <ace/OS_NS_time.h>
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# include <ace/config-all.h>
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
|
||||
std::string LogMessage::getTimeStr(time_t time)
|
||||
{
|
||||
tm* aTm = localtime(&time);
|
||||
tm aTm;
|
||||
ACE_OS::localtime_r(&time, &aTm);
|
||||
char buf[20];
|
||||
snprintf(buf, 20, "%04d-%02d-%02d_%02d:%02d:%02d", aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
|
||||
snprintf(buf, 20, "%04d-%02d-%02d_%02d:%02d:%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +295,8 @@ void Log::write(LogMessage* msg)
|
||||
std::string Log::GetTimestampStr()
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
tm* aTm = localtime(&t);
|
||||
tm aTm;
|
||||
ACE_OS::localtime_r(&t, &aTm);
|
||||
// YYYY year
|
||||
// MM month (2 digits 01-12)
|
||||
// DD day (2 digits 01-31)
|
||||
@@ -303,7 +304,7 @@ std::string Log::GetTimestampStr()
|
||||
// MM minutes (2 digits 00-59)
|
||||
// SS seconds (2 digits 00-59)
|
||||
char buf[20];
|
||||
snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
|
||||
snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -457,8 +457,9 @@ class ByteBuffer
|
||||
|
||||
void AppendPackedTime(time_t time)
|
||||
{
|
||||
tm* lt = localtime(&time);
|
||||
append<uint32>((lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min);
|
||||
tm lt;
|
||||
ACE_OS::localtime_r(&time, <);
|
||||
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
|
||||
}
|
||||
|
||||
void put(size_t pos, const uint8 *src, size_t cnt)
|
||||
|
||||
@@ -215,7 +215,8 @@ uint32 TimeStringToSecs(const std::string& timestring)
|
||||
|
||||
std::string TimeToTimestampStr(time_t t)
|
||||
{
|
||||
tm* aTm = localtime(&t);
|
||||
tm aTm;
|
||||
ACE_OS::localtime_r(&t, &aTm);
|
||||
// YYYY year
|
||||
// MM month (2 digits 01-12)
|
||||
// DD day (2 digits 01-31)
|
||||
@@ -223,7 +224,7 @@ std::string TimeToTimestampStr(time_t t)
|
||||
// MM minutes (2 digits 00-59)
|
||||
// SS seconds (2 digits 00-59)
|
||||
char buf[20];
|
||||
snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
|
||||
snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user