make queue_testutils logging thread-safe and test it
Change-Id: I0d1ed4831cb3cfde4a172839bcc1f2b02756f5f3
diff --git a/aos/build/aos_all.gyp b/aos/build/aos_all.gyp
index 4d28c5c..10d5a5b 100644
--- a/aos/build/aos_all.gyp
+++ b/aos/build/aos_all.gyp
@@ -35,6 +35,7 @@
'<(AOS)/common/common.gyp:condition_test',
'<(AOS)/common/common.gyp:once_test',
'<(AOS)/common/common.gyp:event_test',
+ '<(AOS)/common/common.gyp:queue_testutils_test',
'<(AOS)/common/logging/logging.gyp:logging_impl_test',
'<(AOS)/common/util/util.gyp:options_test',
'<(AOS)/common/common.gyp:queue_test',
diff --git a/aos/common/common.gyp b/aos/common/common.gyp
index f5db470..461200e 100644
--- a/aos/common/common.gyp
+++ b/aos/common/common.gyp
@@ -21,6 +21,7 @@
'<(AOS)/build/aos.gyp:logging',
'once',
'<(AOS)/linux_code/ipc_lib/ipc_lib.gyp:shared_mem',
+ 'mutex',
],
'export_dependent_settings': [
'<(AOS)/linux_code/ipc_lib/ipc_lib.gyp:shared_mem',
@@ -244,11 +245,9 @@
'dependencies': [
'<(AOS)/linux_code/ipc_lib/ipc_lib.gyp:aos_sync',
'<(AOS)/build/aos.gyp:logging_interface',
- 'die',
],
'export_dependent_settings': [
'<(AOS)/linux_code/ipc_lib/ipc_lib.gyp:aos_sync',
- 'die',
],
},
{
@@ -266,6 +265,18 @@
],
},
{
+ 'target_name': 'queue_testutils_test',
+ 'type': 'executable',
+ 'sources': [
+ 'queue_testutils_test.cc',
+ ],
+ 'dependencies': [
+ '<(EXTERNALS):gtest',
+ 'queue_testutils',
+ '<(AOS)/build/aos.gyp:logging',
+ ],
+ },
+ {
'target_name': 'mutex_test',
'type': 'executable',
'sources': [
diff --git a/aos/common/queue_testutils.cc b/aos/common/queue_testutils.cc
index d71d023..a40b5e9 100644
--- a/aos/common/queue_testutils.cc
+++ b/aos/common/queue_testutils.cc
@@ -10,6 +10,7 @@
#include "aos/common/queue.h"
#include "aos/common/logging/logging_impl.h"
#include "aos/common/once.h"
+#include "aos/common/mutex.h"
using ::aos::logging::LogMessage;
@@ -31,11 +32,13 @@
// Clears out all of the messages already recorded.
void ClearMessages() {
+ ::aos::MutexLocker locker(&messages_mutex_);
messages_.clear();
}
// Prints out all of the messages (like when a test fails).
void PrintAllMessages() {
+ ::aos::MutexLocker locker(&messages_mutex_);
for (auto it = messages_.begin(); it != messages_.end(); ++it) {
logging::internal::PrintMessage(stdout, *it);
}
@@ -66,6 +69,7 @@
}
virtual void HandleMessage(const LogMessage &message) override {
+ ::aos::MutexLocker locker(&messages_mutex_);
if (message.level == FATAL || print_as_messages_come_in_) {
logging::internal::PrintMessage(output_file_, message);
}
@@ -76,6 +80,7 @@
::std::vector<LogMessage> messages_;
bool print_as_messages_come_in_ = false;
FILE *output_file_ = stdout;
+ ::aos::Mutex messages_mutex_;
};
class MyTestEventListener : public ::testing::EmptyTestEventListener {
diff --git a/aos/common/queue_testutils_test.cc b/aos/common/queue_testutils_test.cc
new file mode 100644
index 0000000..2defe74
--- /dev/null
+++ b/aos/common/queue_testutils_test.cc
@@ -0,0 +1,31 @@
+#include "aos/common/queue_testutils.h"
+
+#include <thread>
+
+#include "gtest/gtest.h"
+
+#include "aos/common/logging/logging.h"
+
+namespace aos {
+namespace common {
+namespace testing {
+
+// Tests logging from multiple threads.
+// tsan used to complain about this.
+TEST(QueueTestutilsTest, MultithreadedLog) {
+ EnableTestLogging();
+
+ ::std::thread thread([]() {
+ for (int i = 0; i < 1000; ++i) {
+ LOG(INFO, "test from thread\n");
+ }
+ });
+ for (int i = 0; i < 1000; ++i) {
+ LOG(INFO, "not from thread\n");
+ }
+ thread.join();
+}
+
+} // namespace testing
+} // namespace common
+} // namespace aos