Common: Add helper for thread-safe localtime()

And use it with fmt instead of fmt::localtime.
pull/3568/head
Stenzek 1 month ago
parent aa929370ba
commit ae77a82ba3
No known key found for this signature in database

@ -56,6 +56,7 @@ add_library(common
small_string.h
string_util.cpp
string_util.h
time_helpers.h
thirdparty/SmallVector.cpp
thirdparty/SmallVector.h
thirdparty/aes.cpp

@ -23,6 +23,7 @@
<ClInclude Include="heap_array.h" />
<ClInclude Include="intrin.h" />
<ClInclude Include="layered_settings_interface.h" />
<ClInclude Include="time_helpers.h" />
<ClInclude Include="log.h" />
<ClInclude Include="log_channels.h" />
<ClInclude Include="lru_cache.h" />
@ -105,6 +106,9 @@
<ItemGroup>
<None Include="thirdparty\usb_key_code_data.inl" />
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
</ItemGroup>
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\marmasm.targets" />
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />

@ -57,6 +57,7 @@
<ClInclude Include="thirdparty\usb_key_code_data.h">
<Filter>thirdparty</Filter>
</ClInclude>
<ClInclude Include="time_helpers.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="small_string.cpp" />
@ -112,4 +113,7 @@
<Filter>thirdparty</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
</ItemGroup>
</Project>

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
#pragma once
#include <ctime>
namespace Common {
inline std::tm LocalTime(std::time_t tvalue)
{
std::tm ttime;
#ifdef _MSC_VER
localtime_s(&ttime, &tvalue);
#else
localtime_r(&tvalue, &ttime);
#endif
return ttime;
}
} // namespace Common

@ -27,6 +27,7 @@
#include "common/progress_callback.h"
#include "common/string_util.h"
#include "common/thirdparty/SmallVector.h"
#include "common/time_helpers.h"
#include "common/timer.h"
#include "fmt/format.h"
@ -1592,17 +1593,8 @@ std::string GameList::FormatTimestamp(std::time_t timestamp)
}
else
{
struct tm ctime = {};
struct tm ttime = {};
const std::time_t ctimestamp = std::time(nullptr);
#ifdef _MSC_VER
localtime_s(&ctime, &ctimestamp);
localtime_s(&ttime, &timestamp);
#else
localtime_r(&ctimestamp, &ctime);
localtime_r(&timestamp, &ttime);
#endif
const std::tm ctime = Common::LocalTime(std::time(nullptr));
const std::tm ttime = Common::LocalTime(timestamp);
if (ctime.tm_year == ttime.tm_year && ctime.tm_yday == ttime.tm_yday)
{
ret = TRANSLATE_STR("GameList", "Today");

@ -34,6 +34,7 @@
#include "common/path.h"
#include "common/string_util.h"
#include "common/thirdparty/SmallVector.h"
#include "common/time_helpers.h"
#include "common/timer.h"
#include "IconsEmoji.h"
@ -44,7 +45,6 @@
#include <array>
#include <atomic>
#include <chrono>
#include <cmath>
#include <deque>
#include <mutex>
@ -1157,7 +1157,8 @@ void SaveStateSelectorUI::InitializeListEntry(ListEntry* li, ExtendedSaveStateIn
if (global)
li->game_details = fmt::format(TRANSLATE_FS("SaveStateSelectorUI", "{} ({})"), ssi->title, ssi->serial);
li->summary = fmt::format(TRANSLATE_FS("SaveStateSelectorUI", DATE_TIME_FORMAT), fmt::localtime(ssi->timestamp));
li->summary = fmt::format(TRANSLATE_FS("SaveStateSelectorUI", DATE_TIME_FORMAT),
Common::LocalTime(static_cast<std::time_t>(ssi->timestamp)));
li->filename = Path::GetFileName(path);
li->slot = slot;
li->global = global;
@ -1440,7 +1441,7 @@ void SaveStateSelectorUI::ShowSlotOSDMessage()
FILESYSTEM_STAT_DATA sd;
std::string date;
if (!path.empty() && FileSystem::StatFile(path.c_str(), &sd))
date = fmt::format(TRANSLATE_FS("SaveStateSelectorUI", DATE_TIME_FORMAT), fmt::localtime(sd.ModificationTime));
date = fmt::format(TRANSLATE_FS("SaveStateSelectorUI", DATE_TIME_FORMAT), Common::LocalTime(sd.ModificationTime));
else
date = TRANSLATE_STR("SaveStateSelectorUI", "no save yet");

@ -67,6 +67,7 @@
#include "common/ryml_helpers.h"
#include "common/string_util.h"
#include "common/task_queue.h"
#include "common/time_helpers.h"
#include "common/timer.h"
#include "IconsEmoji.h"
@ -80,6 +81,7 @@
#include "xxhash.h"
#include <cctype>
#include <chrono>
#include <cinttypes>
#include <cmath>
#include <cstdio>
@ -351,7 +353,7 @@ static StateVars s_state;
static TinyString GetTimestampStringForFileName()
{
return TinyString::from_format("{:%Y-%m-%d-%H-%M-%S}", fmt::localtime(std::time(nullptr)));
return TinyString::from_format("{:%Y-%m-%d-%H-%M-%S}", Common::LocalTime(std::time(nullptr)));
}
bool System::PerformEarlyHardwareChecks(Error* error)

@ -37,6 +37,7 @@
#include "common/path.h"
#include "common/string_util.h"
#include "common/threading.h"
#include "common/time_helpers.h"
#include "IconsEmoji.h"
#include "fmt/format.h"
@ -1415,15 +1416,8 @@ std::string Host::FormatNumber(NumberFormatType type, s64 value)
DefaultCaseIsUnreachable();
}
struct tm ttime = {};
const std::time_t tvalue = static_cast<std::time_t>(value);
#ifdef _MSC_VER
localtime_s(&ttime, &tvalue);
#else
localtime_r(&tvalue, &ttime);
#endif
char buf[128];
const std::tm ttime = Common::LocalTime(static_cast<std::time_t>(value));
std::strftime(buf, std::size(buf), format, &ttime);
ret.assign(buf);
}

@ -34,6 +34,7 @@
#include "common/sha256_digest.h"
#include "common/string_util.h"
#include "common/threading.h"
#include "common/time_helpers.h"
#include "common/timer.h"
#include "fmt/format.h"
@ -604,15 +605,8 @@ std::string Host::FormatNumber(NumberFormatType type, s64 value)
DefaultCaseIsUnreachable();
}
struct tm ttime = {};
const std::time_t tvalue = static_cast<std::time_t>(value);
#ifdef _MSC_VER
localtime_s(&ttime, &tvalue);
#else
localtime_r(&tvalue, &ttime);
#endif
char buf[128];
const std::tm ttime = Common::LocalTime(static_cast<std::time_t>(value));
std::strftime(buf, std::size(buf), format, &ttime);
ret.assign(buf);
}

@ -10,6 +10,7 @@
#include "common/file_system.h"
#include "common/progress_callback.h"
#include "common/string_util.h"
#include "common/time_helpers.h"
#include "fmt/format.h"
@ -572,14 +573,8 @@ std::string IsoReader::ISODirectoryEntryDateTime::GetFormattedTime() const
const s32 uts_offset = static_cast<s32>(gmt_offset) * 3600;
const time_t uts = std::mktime(&utime) + uts_offset;
struct tm ltime;
#ifdef _MSC_VER
localtime_s(&ltime, &uts);
#else
localtime_r(&uts, &ltime);
#endif
char buf[128];
const std::tm ltime = Common::LocalTime(uts);
const size_t len = std::strftime(buf, std::size(buf), "%c", &ltime);
return std::string(buf, len);
}

Loading…
Cancel
Save