From 0ede7f281ee2521edae5ebf2ea3ff0ff2efad901 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 23 Nov 2016 18:34:28 +0000 Subject: [PATCH] Make log(), error() and fatal() thread-safe. llvm-svn: 287794 --- lld/ELF/Error.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lld/ELF/Error.cpp b/lld/ELF/Error.cpp index 2c2dead6d8de..3afaedbd9f93 100644 --- a/lld/ELF/Error.cpp +++ b/lld/ELF/Error.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" +#include #if !defined(_MSC_VER) && !defined(__MINGW32__) #include @@ -28,19 +29,28 @@ uint64_t elf::ErrorCount; raw_ostream *elf::ErrorOS; StringRef elf::Argv0; +// The functions defined in this file can be called from multiple threads, +// but outs() or errs() are not thread-safe. We protect them using a mutex. +static std::mutex Mu; + void elf::log(const Twine &Msg) { + std::lock_guard Lock(Mu); if (Config->Verbose) outs() << Argv0 << ": " << Msg << "\n"; } void elf::warn(const Twine &Msg) { - if (Config->FatalWarnings) + if (Config->FatalWarnings) { error(Msg); - else - *ErrorOS << Argv0 << ": warning: " << Msg << "\n"; + return; + } + std::lock_guard Lock(Mu); + *ErrorOS << Argv0 << ": warning: " << Msg << "\n"; } void elf::error(const Twine &Msg) { + std::lock_guard Lock(Mu); + if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) { *ErrorOS << Argv0 << ": error: " << Msg << "\n"; } else if (ErrorCount == Config->ErrorLimit) { @@ -69,6 +79,7 @@ void elf::exitLld(int Val) { } void elf::fatal(const Twine &Msg) { + std::lock_guard Lock(Mu); *ErrorOS << Argv0 << ": error: " << Msg << "\n"; exitLld(1); }