Avoid recursion if logging lock is corrupt.

If the logging lock is corrupt then using LOG fails and recursive death ensues.
Make Mutex a friend of LogMessage so that it can do raw logging in this special
situation.
Opportunistically also make fields of LogMessage and LogMessageData that can be
const, const.

Change-Id: I9e0d07c3224096bcf03d6410cd64bb8b5c831fac
diff --git a/src/base/logging.h b/src/base/logging.h
index 310357d..f250ce0 100644
--- a/src/base/logging.h
+++ b/src/base/logging.h
@@ -170,10 +170,10 @@
  public:
   LogMessageData(const char* file, int line, LogSeverity severity, int error);
   std::ostringstream buffer;
-  const char* file;
-  int line_number;
-  LogSeverity severity;
-  int error;
+  const char* const file;
+  const int line_number;
+  const LogSeverity severity;
+  const int error;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(LogMessageData);
@@ -190,9 +190,10 @@
  private:
   static void LogLine(const LogMessageData& data, const char*);
 
-  LogMessageData* data_;
+  LogMessageData* const data_;
 
   friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context);
+  friend class Mutex;
   DISALLOW_COPY_AND_ASSIGN(LogMessage);
 };
 
diff --git a/src/base/mutex.cc b/src/base/mutex.cc
index 86356a9..a2851e5 100644
--- a/src/base/mutex.cc
+++ b/src/base/mutex.cc
@@ -394,7 +394,15 @@
         }
       }
     } else {
-      LOG(FATAL) << "Unexpected state_:" << cur_state << " for " << name_;
+      // Logging acquires the logging lock, avoid infinite recursion in that case.
+      if (this != Locks::logging_lock_) {
+        LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_;
+      } else {
+        LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
+        LogMessage::LogLine(data, StringPrintf("Unexpected state_ %d in unlock for %s",
+                                               cur_state, name_).c_str());
+        _exit(1);
+      }
     }
   } while(!done);
 #else