A bit further along the track of multiple threads.
This also makes valgrind happy, and tsan mostly happy. (The heap, it turns out,
doesn't have a lock yet.)
The DexVerifier changes are just to make valgrind happy, and the code a little
less unidiomatic.
Change-Id: Ic5d436b4863b9d7088eb0b8fe9d32308919899d8
diff --git a/src/logging.cc b/src/logging.cc
index c59a099..03788c3 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -17,26 +17,43 @@
#include "logging.h"
#include "runtime.h"
+#include "thread.h"
#include "utils.h"
+namespace {
+
+art::Mutex* GetLoggingLock() {
+ static art::Mutex* lock = art::Mutex::Create("LogMessage lock");
+ return lock;
+}
+
+}
+
LogMessage::~LogMessage() {
+ // Finish constructing the message.
if (errno_ != -1) {
buffer_ << ": " << strerror(errno_);
}
std::string msg(buffer_.str());
- if (msg.find('\n') == std::string::npos) {
- LogLine(msg.c_str());
- } else {
- msg += '\n';
- size_t i = 0;
- while (i < msg.size()) {
- size_t nl = msg.find('\n', i);
- msg[nl] = '\0';
- LogLine(&msg[i]);
- i = nl + 1;
+
+ // Do the actual logging with the lock held.
+ {
+ art::MutexLock mu(GetLoggingLock());
+ if (msg.find('\n') == std::string::npos) {
+ LogLine(msg.c_str());
+ } else {
+ msg += '\n';
+ size_t i = 0;
+ while (i < msg.size()) {
+ size_t nl = msg.find('\n', i);
+ msg[nl] = '\0';
+ LogLine(&msg[i]);
+ i = nl + 1;
+ }
}
}
+ // Abort if necessary.
if (severity_ == FATAL) {
art::Runtime::Abort(file_, line_number_);
}