summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/Android.mk12
-rw-r--r--base/logging.cpp90
-rw-r--r--base/logging_test.cpp18
-rw-r--r--base/test_main.cpp5
4 files changed, 102 insertions, 23 deletions
diff --git a/base/Android.mk b/base/Android.mk
index ad85c6bac..7bd317b77 100644
--- a/base/Android.mk
+++ b/base/Android.mk
@@ -18,11 +18,13 @@ LOCAL_PATH := $(call my-dir)
libbase_src_files := \
file.cpp \
+ logging.cpp \
stringprintf.cpp \
strings.cpp \
libbase_test_src_files := \
file_test.cpp \
+ logging_test.cpp \
stringprintf_test.cpp \
strings_test.cpp \
test_main.cpp \
@@ -38,7 +40,7 @@ libbase_cppflags := \
include $(CLEAR_VARS)
LOCAL_MODULE := libbase
LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(libbase_src_files) logging.cpp
+LOCAL_SRC_FILES := $(libbase_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
@@ -61,9 +63,6 @@ include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libbase
LOCAL_SRC_FILES := $(libbase_src_files)
-ifneq ($(HOST_OS),windows)
- LOCAL_SRC_FILES += logging.cpp
-endif
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
@@ -85,7 +84,7 @@ include $(BUILD_HOST_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libbase_test
LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(libbase_test_src_files) logging_test.cpp
+LOCAL_SRC_FILES := $(libbase_test_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_SHARED_LIBRARIES := libbase
@@ -97,9 +96,6 @@ include $(BUILD_NATIVE_TEST)
include $(CLEAR_VARS)
LOCAL_MODULE := libbase_test
LOCAL_SRC_FILES := $(libbase_test_src_files)
-ifneq ($(HOST_OS),windows)
- LOCAL_SRC_FILES += logging_test.cpp
-endif
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CPPFLAGS := $(libbase_cppflags)
LOCAL_SHARED_LIBRARIES := libbase
diff --git a/base/logging.cpp b/base/logging.cpp
index 0142b7078..83957b38d 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -27,12 +27,19 @@
#include <iostream>
#include <limits>
-#include <mutex>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
+#ifndef _WIN32
+#include <mutex>
+#else
+#define NOGDI // Suppress the evil ERROR macro.
+#include <windows.h>
+#endif
+
+#include "base/macros.h"
#include "base/strings.h"
#include "cutils/threads.h"
@@ -45,10 +52,79 @@
#include <unistd.h>
#endif
+namespace {
+#ifndef _WIN32
+using std::mutex;
+using std::lock_guard;
+
+#if defined(__GLIBC__)
+const char* getprogname() {
+ return program_invocation_short_name;
+}
+#endif
+
+#else
+const char* getprogname() {
+ static bool first = true;
+ static char progname[MAX_PATH] = {};
+
+ if (first) {
+ // TODO(danalbert): This is a full path on Windows. Just get the basename.
+ DWORD nchars = GetModuleFileName(nullptr, progname, sizeof(progname));
+ DCHECK_GT(nchars, 0U);
+ first = false;
+ }
+
+ return progname;
+}
+
+class mutex {
+ public:
+ mutex() {
+ semaphore_ = CreateSemaphore(nullptr, 1, 1, nullptr);
+ CHECK(semaphore_ != nullptr) << "Failed to create Mutex";
+ }
+ ~mutex() {
+ CloseHandle(semaphore_);
+ }
+
+ void lock() {
+ DWORD result = WaitForSingleObject(semaphore_, INFINITE);
+ CHECK_EQ(result, WAIT_OBJECT_0) << GetLastError();
+ }
+
+ void unlock() {
+ bool result = ReleaseSemaphore(semaphore_, 1, nullptr);
+ CHECK(result);
+ }
+
+ private:
+ HANDLE semaphore_;
+};
+
+template <typename LockT>
+class lock_guard {
+ public:
+ explicit lock_guard(LockT& lock) : lock_(lock) {
+ lock_.lock();
+ }
+
+ ~lock_guard() {
+ lock_.unlock();
+ }
+
+ private:
+ LockT& lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(lock_guard);
+};
+#endif
+} // namespace
+
namespace android {
namespace base {
-static std::mutex logging_lock;
+static mutex logging_lock;
#ifdef __ANDROID__
static LogFunction gLogger = LogdLogger();
@@ -60,12 +136,6 @@ static bool gInitialized = false;
static LogSeverity gMinimumLogSeverity = INFO;
static std::unique_ptr<std::string> gProgramInvocationName;
-#if defined(__GLIBC__)
-static const char* getprogname() {
- return program_invocation_short_name;
-}
-#endif
-
static const char* ProgramInvocationName() {
if (gProgramInvocationName == nullptr) {
gProgramInvocationName.reset(new std::string(getprogname()));
@@ -182,7 +252,7 @@ void InitLogging(char* argv[]) {
}
void SetLogger(LogFunction&& logger) {
- std::lock_guard<std::mutex> lock(logging_lock);
+ lock_guard<mutex> lock(logging_lock);
gLogger = std::move(logger);
}
@@ -287,7 +357,7 @@ std::ostream& LogMessage::stream() {
void LogMessage::LogLine(const char* file, unsigned int line, LogId id,
LogSeverity severity, const char* message) {
const char* tag = ProgramInvocationName();
- std::lock_guard<std::mutex> lock(logging_lock);
+ lock_guard<mutex> lock(logging_lock);
gLogger(id, severity, tag, file, line, message);
}
diff --git a/base/logging_test.cpp b/base/logging_test.cpp
index d947c1d9f..c91857a0a 100644
--- a/base/logging_test.cpp
+++ b/base/logging_test.cpp
@@ -85,6 +85,9 @@ std::string make_log_pattern(android::base::LogSeverity severity,
TEST(logging, LOG) {
ASSERT_DEATH(LOG(FATAL) << "foobar", "foobar");
+ // We can't usefully check the output of any of these on Windows because we
+ // don't have std::regex, but we can at least make sure we printed at least as
+ // many characters are in the log message.
{
CapturedStderr cap;
LOG(WARNING) << "foobar";
@@ -92,10 +95,13 @@ TEST(logging, LOG) {
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(
make_log_pattern(android::base::WARNING, "foobar"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
{
@@ -105,10 +111,13 @@ TEST(logging, LOG) {
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(
make_log_pattern(android::base::INFO, "foobar"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
{
@@ -129,10 +138,13 @@ TEST(logging, LOG) {
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(
make_log_pattern(android::base::DEBUG, "foobar"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
}
@@ -145,10 +157,13 @@ TEST(logging, PLOG) {
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("foobar"));
+#if !defined(_WIN32)
std::regex message_regex(make_log_pattern(
android::base::INFO, "foobar: No such file or directory"));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
}
@@ -161,11 +176,14 @@ TEST(logging, UNIMPLEMENTED) {
std::string output;
android::base::ReadFdToString(cap.fd(), &output);
+ ASSERT_GT(output.length(), strlen("unimplemented"));
+#if !defined(_WIN32)
std::string expected_message =
android::base::StringPrintf("%s unimplemented ", __PRETTY_FUNCTION__);
std::regex message_regex(
make_log_pattern(android::base::ERROR, expected_message.c_str()));
ASSERT_TRUE(std::regex_search(output, message_regex));
+#endif
}
}
diff --git a/base/test_main.cpp b/base/test_main.cpp
index c362b6c51..546923d9b 100644
--- a/base/test_main.cpp
+++ b/base/test_main.cpp
@@ -20,11 +20,6 @@
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
-
- // No logging on Windows yet.
-#if !defined(_WIN32)
android::base::InitLogging(argv, android::base::StderrLogger);
-#endif
-
return RUN_ALL_TESTS();
}