summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2017-02-26 15:15:08 -0500
committerAndrew Morrow <acm@mongodb.com>2017-08-02 23:29:55 -0400
commita8a1ea3b9367adb6d0b65a7da21fed89598ea093 (patch)
tree8e969ed54b88c2a9c4c2d45a6518d053ac9f4265 /src/mongo/util
parentc02c14e30d75b02894da116f4bb1a71652ead2b4 (diff)
downloadmongo-a8a1ea3b9367adb6d0b65a7da21fed89598ea093.tar.gz
SERVER-26538 SERVER-26539 Detach from boost::thread
Also, use thread_local everywhere for our thread specific data needs and remove the legacy support.
Diffstat (limited to 'src/mongo/util')
-rw-r--r--src/mongo/util/concurrency/idle_thread_block.cpp3
-rw-r--r--src/mongo/util/concurrency/thread_name.cpp7
-rw-r--r--src/mongo/util/concurrency/threadlocal.h138
-rw-r--r--src/mongo/util/fail_point.cpp28
-rw-r--r--src/mongo/util/log.cpp1
-rw-r--r--src/mongo/util/net/ssl_manager.cpp27
-rw-r--r--src/mongo/util/signal_handlers_synchronous.cpp7
-rw-r--r--src/mongo/util/time_support.cpp14
8 files changed, 36 insertions, 189 deletions
diff --git a/src/mongo/util/concurrency/idle_thread_block.cpp b/src/mongo/util/concurrency/idle_thread_block.cpp
index d81bbdecd7a..d81f920f9cb 100644
--- a/src/mongo/util/concurrency/idle_thread_block.cpp
+++ b/src/mongo/util/concurrency/idle_thread_block.cpp
@@ -29,12 +29,11 @@
#include "mongo/util/assert_util.h"
#include "mongo/util/concurrency/idle_thread_block.h"
-#include "mongo/util/concurrency/threadlocal.h"
namespace mongo {
namespace for_debuggers {
// This needs external linkage to ensure that debuggers can use it.
-MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL const char* idleThreadLocation = nullptr;
+thread_local const char* idleThreadLocation = nullptr;
}
using for_debuggers::idleThreadLocation;
diff --git a/src/mongo/util/concurrency/thread_name.cpp b/src/mongo/util/concurrency/thread_name.cpp
index 2c2470a5ad5..4bf6aa71f6c 100644
--- a/src/mongo/util/concurrency/thread_name.cpp
+++ b/src/mongo/util/concurrency/thread_name.cpp
@@ -31,8 +31,6 @@
#include "mongo/util/concurrency/thread_name.h"
-#include <boost/thread/tss.hpp>
-
#if defined(__APPLE__) || defined(__linux__)
#include <pthread.h>
#endif
@@ -52,7 +50,6 @@
#include "mongo/base/init.h"
#include "mongo/config.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/util/concurrency/threadlocal.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
@@ -110,13 +107,13 @@ MONGO_INITIALIZER(ThreadNameInitializer)(InitializerContext*) {
// TODO consider making threadName std::string and removing the size limit once we get real
// thread_local.
constexpr size_t kMaxThreadNameSize = 63;
-MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL char threadNameStorage[kMaxThreadNameSize + 1];
+thread_local char threadNameStorage[kMaxThreadNameSize + 1];
} // namespace
namespace for_debuggers {
// This needs external linkage to ensure that debuggers can use it.
-MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL StringData threadName;
+thread_local StringData threadName;
}
using for_debuggers::threadName;
diff --git a/src/mongo/util/concurrency/threadlocal.h b/src/mongo/util/concurrency/threadlocal.h
deleted file mode 100644
index d6190bffb0f..00000000000
--- a/src/mongo/util/concurrency/threadlocal.h
+++ /dev/null
@@ -1,138 +0,0 @@
-#pragma once
-
-/**
-* Copyright (C) 2011 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects
-* for all of the code used other than as permitted herein. If you modify
-* file(s) with this exception, you may extend this exception to your
-* version of the file(s), but you are not obligated to do so. If you do not
-* wish to do so, delete this exception statement from your version. If you
-* delete this exception statement from all source files in the program,
-* then also delete it in the license file.
-*/
-
-#include <boost/thread/tss.hpp>
-
-#include "mongo/config.h"
-
-#include "mongo/base/disallow_copying.h"
-
-#if defined(MONGO_CONFIG_HAVE_THREAD_LOCAL)
-#define MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL thread_local
-#elif defined(MONGO_CONFIG_HAVE___THREAD)
-#define MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL __thread
-#elif defined(MONGO_CONFIG_HAVE___DECLSPEC_THREAD)
-#define MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL __declspec(thread)
-#else
-#error "Compiler must support trivially constructible thread local variables"
-#endif
-
-namespace mongo {
-
-using boost::thread_specific_ptr;
-
-/**
- * DEPRECATED, DO NOT USE.
- *
- * thread local "value" rather than a pointer
- * good for things which have copy constructors (and the copy constructor is fast enough)
- * e.g.
- * ThreadLocalValue<int> myint;
- */
-template <class T>
-class ThreadLocalValue {
-public:
- ThreadLocalValue(T def = 0) : _default(def) {}
-
- T get() const {
- T* val = _val.get();
- if (val)
- return *val;
- return _default;
- }
-
- void set(const T& i) {
- T* v = _val.get();
- if (v) {
- *v = i;
- return;
- }
- v = new T(i);
- _val.reset(v);
- }
-
- T& getRef() {
- T* v = _val.get();
- if (v) {
- return *v;
- }
- v = new T(_default);
- _val.reset(v);
- return *v;
- }
-
-private:
- boost::thread_specific_ptr<T> _val;
- const T _default;
-};
-
-/**
- * Emulation of a thread local storage specifier used because not all supported
- * compiler toolchains support the C++11 thread_local storage class keyword.
- *
- * Since all supported toolchains do support a thread local storage class for
- * types that are trivially constructible and destructible, we perform the
- * emulation using that storage type and the machinery of boost::thread_specific_ptr to
- * handle deleting the objects on thread termination.
- */
-template <class T>
-class TSP {
- MONGO_DISALLOW_COPYING(TSP);
-
-public:
- TSP() = default;
- T* get() const;
- void reset(T* v);
- T* getMake() {
- T* t = get();
- if (t == nullptr)
- reset(t = new T());
- return t;
- }
-
-private:
- boost::thread_specific_ptr<T> tsp;
-};
-
-#define TSP_DECLARE(T, p) extern TSP<T> p;
-
-#define TSP_DEFINE(T, p) \
- MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL T* _##p; \
- TSP<T> p; \
- template <> \
- T* TSP<T>::get() const { \
- return _##p; \
- } \
- template <> \
- void TSP<T>::reset(T* v) { \
- tsp.reset(v); \
- _##p = v; \
- }
-} // namespace mongo
diff --git a/src/mongo/util/fail_point.cpp b/src/mongo/util/fail_point.cpp
index d4d53e36835..8f85ba18f17 100644
--- a/src/mongo/util/fail_point.cpp
+++ b/src/mongo/util/fail_point.cpp
@@ -32,8 +32,8 @@
#include "mongo/bson/util/bson_extract.h"
#include "mongo/platform/random.h"
+#include "mongo/stdx/memory.h"
#include "mongo/stdx/thread.h"
-#include "mongo/util/concurrency/threadlocal.h"
#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
@@ -43,8 +43,7 @@ namespace mongo {
namespace {
/**
- * Type representing the per-thread PRNG used by fail-points. Required because TSP_* macros,
- * below, only let you create one thread-specific object per type.
+ * Type representing the per-thread PRNG used by fail-points.
*/
class FailPointPRNG {
public:
@@ -58,26 +57,23 @@ public:
return _prng.nextInt32() & ~(1 << 31);
}
+ static FailPointPRNG* current() {
+ if (!_failPointPrng)
+ _failPointPrng = stdx::make_unique<FailPointPRNG>();
+ return _failPointPrng.get();
+ }
+
private:
PseudoRandom _prng;
+ static thread_local std::unique_ptr<FailPointPRNG> _failPointPrng;
};
-} // namespace
-
-
-TSP_DECLARE(FailPointPRNG, failPointPrng);
-TSP_DEFINE(FailPointPRNG, failPointPrng);
-
-namespace {
-
-int32_t prngNextPositiveInt32() {
- return failPointPrng.getMake()->nextPositiveInt32();
-}
+thread_local std::unique_ptr<FailPointPRNG> FailPointPRNG::_failPointPrng;
} // namespace
void FailPoint::setThreadPRNGSeed(int32_t seed) {
- failPointPrng.getMake()->resetSeed(seed);
+ FailPointPRNG::current()->resetSeed(seed);
}
FailPoint::FailPoint() : _fpInfo(0), _mode(off), _timesOrPeriod(0) {}
@@ -158,7 +154,7 @@ FailPoint::RetCode FailPoint::slowShouldFailOpenBlock() {
case random: {
const AtomicInt32::WordType maxActivationValue = _timesOrPeriod.load();
- if (prngNextPositiveInt32() < maxActivationValue) {
+ if (FailPointPRNG::current()->nextPositiveInt32() < maxActivationValue) {
return slowOn;
}
return slowOff;
diff --git a/src/mongo/util/log.cpp b/src/mongo/util/log.cpp
index 76bc1ac8837..7c21dccd079 100644
--- a/src/mongo/util/log.cpp
+++ b/src/mongo/util/log.cpp
@@ -37,7 +37,6 @@
#include "mongo/logger/rotatable_file_manager.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/concurrency/thread_name.h"
-#include "mongo/util/concurrency/threadlocal.h"
#include "mongo/util/stacktrace.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index c5b911ca6b2..b5b379ce31a 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -33,8 +33,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/thread.hpp>
#include <iostream>
#include <sstream>
#include <string>
@@ -48,7 +46,6 @@
#include "mongo/stdx/memory.h"
#include "mongo/transport/session.h"
#include "mongo/util/concurrency/mutex.h"
-#include "mongo/util/concurrency/threadlocal.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/exit.h"
#include "mongo/util/log.h"
@@ -189,7 +186,20 @@ const STACK_OF(X509_EXTENSION) * X509_get0_extensions(const X509* peerCert) {
class SSLThreadInfo {
public:
static unsigned long getID() {
- enforceCleanupOnShutdown();
+ // NOTE: This logic is fully intentional. Because ERR_remove_state (called within
+ // the destructor of the kRemoveStateFromThread object) re-enters this function,
+ // we must have a two phase protection, otherwise we would access a thread local
+ // during its destruction.
+ static thread_local bool firstCall = false;
+ if (!firstCall) {
+ firstCall = true;
+
+ static const thread_local struct CallErrRemoveState {
+ ~CallErrRemoveState() {
+ ERR_remove_state(0);
+ };
+ } kRemoveStateFromThread{};
+ }
#ifdef _WIN32
return GetCurrentThreadId();
@@ -221,15 +231,6 @@ public:
private:
SSLThreadInfo() = delete;
- // When called, ensures that this thread will, on termination, call ERR_remove_state.
- static void enforceCleanupOnShutdown() {
- static MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL bool firstCall = true;
- if (firstCall) {
- boost::this_thread::at_thread_exit([] { ERR_remove_state(0); });
- firstCall = false;
- }
- }
-
// Note: see SERVER-8734 for why we are using a recursive mutex here.
// Once the deadlock fix in OpenSSL is incorporated into most distros of
// Linux, this can be changed back to a nonrecursive mutex.
diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp
index 8107143ef55..2331190fabc 100644
--- a/src/mongo/util/signal_handlers_synchronous.cpp
+++ b/src/mongo/util/signal_handlers_synchronous.cpp
@@ -48,7 +48,6 @@
#include "mongo/platform/compiler.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/thread_name.h"
-#include "mongo/util/concurrency/threadlocal.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/debugger.h"
#include "mongo/util/exception_filter_win32.h"
@@ -156,12 +155,12 @@ public:
private:
static stdx::mutex _streamMutex;
- static MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL int terminateDepth;
+ static thread_local int terminateDepth;
stdx::unique_lock<stdx::mutex> _lk;
};
+
stdx::mutex MallocFreeOStreamGuard::_streamMutex;
-MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL
-int MallocFreeOStreamGuard::terminateDepth = 0;
+thread_local int MallocFreeOStreamGuard::terminateDepth = 0;
// must hold MallocFreeOStreamGuard to call
void writeMallocFreeStreamToLog() {
diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp
index 7ab7a03215d..eb318a2a6cd 100644
--- a/src/mongo/util/time_support.cpp
+++ b/src/mongo/util/time_support.cpp
@@ -29,7 +29,6 @@
#include "mongo/util/time_support.h"
-#include <boost/thread/tss.hpp>
#include <cstdint>
#include <cstdio>
#include <iostream>
@@ -82,7 +81,7 @@ bool Date_t::isFormattable() const {
// jsTime_virtual_skew is just for testing. a test command manipulates it.
long long jsTime_virtual_skew = 0;
-boost::thread_specific_ptr<long long> jsTime_virtual_thread_skew;
+thread_local long long jsTime_virtual_thread_skew = 0;
using std::string;
@@ -770,9 +769,6 @@ int Backoff::getNextSleepMillis(int lastSleepMillis,
return lastSleepMillis;
}
-extern long long jsTime_virtual_skew;
-extern boost::thread_specific_ptr<long long> jsTime_virtual_thread_skew;
-
// DO NOT TOUCH except for testing
void jsTimeVirtualSkew(long long skew) {
jsTime_virtual_skew = skew;
@@ -782,13 +778,11 @@ long long getJSTimeVirtualSkew() {
}
void jsTimeVirtualThreadSkew(long long skew) {
- jsTime_virtual_thread_skew.reset(new long long(skew));
+ jsTime_virtual_thread_skew = skew;
}
+
long long getJSTimeVirtualThreadSkew() {
- if (jsTime_virtual_thread_skew.get()) {
- return *(jsTime_virtual_thread_skew.get());
- } else
- return 0;
+ return jsTime_virtual_thread_skew;
}
/** Date_t is milliseconds since epoch */