diff --git a/src/services/network_refresh_service.cpp b/src/services/network_refresh_service.cpp index b776b3c..fefc08e 100644 --- a/src/services/network_refresh_service.cpp +++ b/src/services/network_refresh_service.cpp @@ -434,8 +434,15 @@ std::optional NetworkRefreshService:: result.market.market_cap = data.value("usd_market_cap", 0.0); char buf[64]; - std::tm* tm = std::localtime(&fetchedAt); - if (tm && std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm) > 0) { + // Runs on the RPC worker thread — std::localtime shares a process-wide static tm, so use the + // reentrant variant into a local tm (matches the rest of the codebase). + std::tm tmv{}; +#ifdef _WIN32 + localtime_s(&tmv, &fetchedAt); +#else + localtime_r(&fetchedAt, &tmv); +#endif + if (std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmv) > 0) { result.market.last_updated = buf; } return result; diff --git a/src/util/logger.cpp b/src/util/logger.cpp index 36de00a..a912767 100644 --- a/src/util/logger.cpp +++ b/src/util/logger.cpp @@ -57,7 +57,15 @@ void Logger::write(const std::string& message) now.time_since_epoch()) % 1000; std::stringstream ss; - ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S"); + // Reachable from worker/monitor threads — std::localtime shares a process-wide static tm, so use the + // reentrant variant into a local tm (the logger's own mutex can't protect other localtime callers). + std::tm tmv{}; +#ifdef _WIN32 + localtime_s(&tmv, &time); +#else + localtime_r(&time, &tmv); +#endif + ss << std::put_time(&tmv, "%Y-%m-%d %H:%M:%S"); ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); ss << " | " << message;