diff options
-rw-r--r-- | base/Android.mk | 12 | ||||
-rw-r--r-- | base/logging.cpp | 90 | ||||
-rw-r--r-- | base/logging_test.cpp | 18 | ||||
-rw-r--r-- | base/test_main.cpp | 5 |
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(); } |