summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmirsaman Memaripour <amirsaman.memaripour@mongodb.com>2020-05-26 14:24:08 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-06-02 16:42:44 +0000
commitf841e415fa8fb7b057c1973f6ff8fc0460de1f08 (patch)
tree1004135f1e42e46a588c4cec5a1b177592393fd8
parenta0c55b0db33e2a3ca23fe8c994ce1045677d6ca6 (diff)
downloadmongo-f841e415fa8fb7b057c1973f6ff8fc0460de1f08.tar.gz
SERVER-48346 Fix lifetime issues for barriers captured by reference
Extends the lifetime of barriers that are referenced by background threads and their reference could outlive the barrier's owner. (cherry picked from commit 3b7bc03a8f8b964769ff708674163b67ddd1a450)
-rw-r--r--src/mongo/executor/thread_pool_task_executor_test.cpp6
-rw-r--r--src/mongo/util/concurrency/thread_pool_test.cpp22
-rw-r--r--src/mongo/util/thread_safety_context_test.cpp12
3 files changed, 18 insertions, 22 deletions
diff --git a/src/mongo/executor/thread_pool_task_executor_test.cpp b/src/mongo/executor/thread_pool_task_executor_test.cpp
index 779b025bb20..fed4f56962d 100644
--- a/src/mongo/executor/thread_pool_task_executor_test.cpp
+++ b/src/mongo/executor/thread_pool_task_executor_test.cpp
@@ -87,6 +87,9 @@ TEST_F(ThreadPoolExecutorTest, Schedule) {
});
barrier.countDownAndWait();
ASSERT_OK(status1);
+ // Wait for the executor to stop to ensure the scheduled job does not outlive current scope.
+ executor.shutdown();
+ executor.join();
}
TEST_F(ThreadPoolExecutorTest, ScheduleAfterShutdown) {
@@ -113,6 +116,9 @@ TEST_F(ThreadPoolExecutorTest, OnEvent) {
executor.signalEvent(event);
barrier.countDownAndWait();
ASSERT_OK(status1);
+ // Wait for the executor to stop to ensure the scheduled job does not outlive current scope.
+ executor.shutdown();
+ executor.join();
}
TEST_F(ThreadPoolExecutorTest, OnEventAfterShutdown) {
diff --git a/src/mongo/util/concurrency/thread_pool_test.cpp b/src/mongo/util/concurrency/thread_pool_test.cpp
index 30e5dbd0ddc..0b456c6abc1 100644
--- a/src/mongo/util/concurrency/thread_pool_test.cpp
+++ b/src/mongo/util/concurrency/thread_pool_test.cpp
@@ -32,8 +32,10 @@
#include "mongo/platform/basic.h"
#include <boost/optional.hpp>
+#include <fmt/format.h>
#include "mongo/base/init.h"
+#include "mongo/platform/atomic_word.h"
#include "mongo/platform/mutex.h"
#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
@@ -48,6 +50,7 @@
namespace {
using namespace mongo;
+using namespace fmt::literals;
MONGO_INITIALIZER(ThreadPoolCommonTests)(InitializerContext*) {
addTestsForThreadPool("ThreadPoolCommon",
@@ -256,29 +259,22 @@ DEATH_TEST_REGEX(ThreadPoolTest,
TEST_F(ThreadPoolTest, ThreadPoolRunsOnCreateThreadFunctionBeforeConsumingTasks) {
unittest::Barrier barrier(2U);
-
- bool onCreateThreadCalled = false;
- std::string taskThreadName;
+ std::string journal;
ThreadPool::Options options;
options.threadNamePrefix = "mythread";
options.maxThreads = 1U;
- options.onCreateThread = [&onCreateThreadCalled,
- &taskThreadName](const std::string& threadName) {
- onCreateThreadCalled = true;
- taskThreadName = threadName;
+ options.onCreateThread = [&](const std::string& threadName) {
+ journal.append("[onCreate({})]"_format(threadName));
};
ThreadPool pool(options);
pool.startup();
-
- pool.schedule([&barrier](auto status) {
- ASSERT_OK(status);
+ pool.schedule([&](auto status) {
+ journal.append("[Call({})]"_format(status.toString()));
barrier.countDownAndWait();
});
barrier.countDownAndWait();
-
- ASSERT_TRUE(onCreateThreadCalled);
- ASSERT_EQUALS(options.threadNamePrefix + "0", taskThreadName);
+ ASSERT_EQUALS(journal, "[onCreate(mythread0)][Call(OK)]");
}
TEST(ThreadPoolTest, JoinAllRetiredThreads) {
diff --git a/src/mongo/util/thread_safety_context_test.cpp b/src/mongo/util/thread_safety_context_test.cpp
index 94d3c45d5b5..189bdc86ee0 100644
--- a/src/mongo/util/thread_safety_context_test.cpp
+++ b/src/mongo/util/thread_safety_context_test.cpp
@@ -29,7 +29,6 @@
#include <vector>
#include "mongo/stdx/thread.h"
-#include "mongo/unittest/barrier.h"
#include "mongo/unittest/death_test.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/thread_safety_context.h"
@@ -78,15 +77,10 @@ DEATH_TEST_F(ThreadSafetyContextTest, CreateThreadsAfterForbidingMultiThreading,
}
DEATH_TEST_F(ThreadSafetyContextTest, ForbidMultiThreadingAfterCreatingThreads, "invariant") {
- unittest::Barrier barrier(2);
+ auto thread = stdx::thread([]() {});
- auto thread = stdx::thread([&]() mutable {
- barrier.countDownAndWait();
- sleepFor(Milliseconds(50));
- });
-
- // Wait for the thread to start before proceeding with the test
- barrier.countDownAndWait();
+ // Wait for the thread to return before proceeding with the test
+ thread.join();
ThreadSafetyContext::getThreadSafetyContext()->forbidMultiThreading();
// Must never reach here or the test fails