Make POSIX SIGTERM/SIGINT/SIGHUP handler async signal safe.
* Don't use LOG/CHECK.  Replace with RAW_LOG/DCHECK (newly added to logging.h)
* Don't directly post a task to the UI loop.  Write to a magic pipe.  Read this from a separate thread which will post to a task to the UI loop.
BUG=http://crbug.com/29240

Review URL: http://codereview.chromium.org/460094

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34036 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: e36ddc88da9374cfa6853101b2b81eb20a081026
diff --git a/base/logging.cc b/base/logging.cc
index af513be..706dbb1 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -5,9 +5,14 @@
 #include "base/logging.h"
 
 #if defined(OS_WIN)
+#include <io.h>
 #include <windows.h>
 typedef HANDLE FileHandle;
 typedef HANDLE MutexHandle;
+// Windows warns on using write().  It prefers _write().
+#define write(fd, buf, count) _write(fd, buf, static_cast<unsigned int>(count))
+// Windows doesn't define STDERR_FILENO.  Define it here.
+#define STDERR_FILENO 2
 #elif defined(OS_MACOSX)
 #include <CoreFoundation/CoreFoundation.h>
 #include <mach/mach.h>
@@ -37,6 +42,7 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/debug_util.h"
+#include "base/eintr_wrapper.h"
 #include "base/lock_impl.h"
 #if defined(OS_POSIX)
 #include "base/safe_strerror_posix.h"
@@ -684,6 +690,37 @@
   log_file = NULL;
 }
 
+void RawLog(int level, const char* message) {
+  if (level >= min_log_level) {
+    size_t bytes_written = 0;
+    const size_t message_len = strlen(message);
+    int rv;
+    while (bytes_written < message_len) {
+      rv = HANDLE_EINTR(
+          write(STDERR_FILENO, message + bytes_written,
+                message_len - bytes_written));
+      if (rv < 0) {
+        // Give up, nothing we can do now.
+        break;
+      }
+      bytes_written += rv;
+    }
+
+    if (message_len > 0 && message[message_len - 1] != '\n') {
+      do {
+        rv = HANDLE_EINTR(write(STDERR_FILENO, "\n", 1));
+        if (rv < 0) {
+          // Give up, nothing we can do now.
+          break;
+        }
+      } while (rv != 1);
+    }
+  }
+
+  if (level == LOG_FATAL)
+    DebugUtil::BreakDebugger();
+}
+
 }  // namespace logging
 
 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) {