Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions src/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,28 @@
using namespace Aws::Utils;
using namespace Aws::Utils::Logging;

static std::shared_ptr<LogSystemInterface> AWSLogSystem(nullptr);
static std::shared_ptr<LogSystemInterface> OldLogger(nullptr);
namespace {

// AWS clients owned by other globals can be destroyed after this translation
// unit's statics (static destruction order across translation units is
// unspecified) and still log through GetLogSystem() while unwinding. The flag
// is trivially destructible, so it stays readable until the very end of the
// process; once ~LoggingSet has cleared it, the accessors below behave as
// if no logger is installed instead of touching the destroyed shared_ptrs.
bool LoggingSetAlive = true;

struct LoggingSet {
std::shared_ptr<LogSystemInterface> AWSLogSystem;
std::shared_ptr<LogSystemInterface> OldLogger;

~LoggingSet() {
LoggingSetAlive = false;
}
};

LoggingSet LogSet;

} // anonymous namespace

namespace Aws
{
Expand All @@ -24,7 +44,9 @@ namespace Utils
namespace Logging {

void InitializeAWSLogging(const std::shared_ptr<LogSystemInterface> &logSystem) {
AWSLogSystem = logSystem;
if (LoggingSetAlive) {
LogSet.AWSLogSystem = logSystem;
}
}

void ShutdownAWSLogging(void) {
Expand All @@ -33,23 +55,31 @@ void ShutdownAWSLogging(void) {
// so this is a hack to let all other threads finish their log statement after getting a LogSystem pointer
// otherwise we would need to perform ref-counting on each logging statement
std::this_thread::sleep_for(std::chrono::milliseconds(1));
OldLogger.reset();
if (LoggingSetAlive) {
LogSet.OldLogger.reset();
}
}

LogSystemInterface *GetLogSystem() {
return AWSLogSystem.get();
return LoggingSetAlive ? LogSet.AWSLogSystem.get() : nullptr;
}

void PushLogger(const std::shared_ptr<LogSystemInterface> &logSystem)
{
OldLogger = AWSLogSystem;
AWSLogSystem = logSystem;
if (!LoggingSetAlive) {
return;
}
LogSet.OldLogger = LogSet.AWSLogSystem;
LogSet.AWSLogSystem = logSystem;
}

void PopLogger()
{
AWSLogSystem = OldLogger;
OldLogger = nullptr;
if (!LoggingSetAlive) {
return;
}
LogSet.AWSLogSystem = LogSet.OldLogger;
LogSet.OldLogger = nullptr;
}

} // namespace Logging
Expand Down