From ac0b3c4052e88c6626b4bd3129d4190e2d0aa179 Mon Sep 17 00:00:00 2001 From: ADAM Martin Date: Mon, 14 Oct 2019 23:21:42 +0000 Subject: SERVER-42736 Remove PosixNSPR implementations. We don't need these implementations as the mozjs code doesn't call into them anymore. Therefore we don't have to either. --- src/mongo/scripting/mozjs/PosixNSPR.cpp | 319 +++++-------------------------- src/mongo/scripting/mozjs/implscope.cpp | 19 +- src/mongo/scripting/mozjs/implscope.h | 2 +- src/mongo/scripting/mozjs/jsthread.cpp | 16 +- src/mongo/scripting/mozjs/proxyscope.cpp | 20 +- src/mongo/scripting/mozjs/proxyscope.h | 4 +- 6 files changed, 60 insertions(+), 320 deletions(-) (limited to 'src/mongo/scripting') diff --git a/src/mongo/scripting/mozjs/PosixNSPR.cpp b/src/mongo/scripting/mozjs/PosixNSPR.cpp index f264b145f22..6df76f4ef13 100644 --- a/src/mongo/scripting/mozjs/PosixNSPR.cpp +++ b/src/mongo/scripting/mozjs/PosixNSPR.cpp @@ -1,19 +1,14 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/** - * This file was copied out of the firefox 38.0.1esr source tree from - * js/src/vm/PosixNSPR.cpp and modified to use the MongoDB threading - * primitives. +/* + * This file was originally copied out of the firefox 38.0.1esr source tree from + * `js/src/vm/PosixNSPR.cpp` and modified to use the MongoDB threading primitives. * - * The point of this file is to shim the posix emulation of nspr that Mozilla - * ships with firefox. We force configuration such that the SpiderMonkey build - * looks for these symbols and we provide them from within our object code - * rather than attempting to build it in there's so we can take advantage of - * the cross platform abstractions that we rely upon. + * The point of this file is to provide dummy implementations such that when the SpiderMonkey build + * looks for these symbols it will find symbols, thus permitting linkage. No code uses these + * entrypoints. */ #include "mongo/platform/basic.h" @@ -29,291 +24,75 @@ #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/time_support.h" -class nspr::Thread { - mongo::stdx::thread thread_; - void (*start)(void* arg); - void* arg; - bool joinable; - -public: - Thread(void (*start)(void* arg), void* arg, bool joinable) - : start(start), arg(arg), joinable(joinable) {} - - static void* ThreadRoutine(void* arg); - - mongo::stdx::thread& thread() { - return thread_; - } -}; - -namespace { -thread_local nspr::Thread* kCurrentThread = nullptr; -} // namespace - -void* nspr::Thread::ThreadRoutine(void* arg) { - Thread* self = static_cast(arg); - kCurrentThread = self; - self->start(self->arg); - if (!self->joinable) - js_delete(self); - return nullptr; -} - -namespace mongo { -namespace mozjs { - -void PR_BindThread(PRThread* thread) { - kCurrentThread = thread; -} - -PRThread* PR_CreateFakeThread() { - return new PRThread(nullptr, nullptr, true); -} - -void PR_DestroyFakeThread(PRThread* thread) { - delete thread; -} -} // namespace mozjs -} // namespace mongo - - -// In mozjs-45, js_delete takes a const pointer which is incompatible with std::unique_ptr. -template -static MOZ_ALWAYS_INLINE void js_delete_nonconst(T* p) { - if (p) { - p->~T(); - js_free(p); - } -} - -PRThread* PR_CreateThread(PRThreadType type, - void (*start)(void* arg), - void* arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - uint32_t stackSize) { - MOZ_ASSERT(type == PR_USER_THREAD); - MOZ_ASSERT(priority == PR_PRIORITY_NORMAL); - - try { - // We can't use the nspr allocator to allocate this thread, because under asan we - // instrument the allocator so that asan can track the pointers correctly. This - // instrumentation - // requires that pointers be deleted in the same thread that they were allocated in. - // The threads created in PR_CreateThread are not always freed in the same thread - // that they were created in. So, we use the standard allocator here. - auto t = std::make_unique(start, arg, state != PR_UNJOINABLE_THREAD); - - t->thread() = mongo::stdx::thread(&nspr::Thread::ThreadRoutine, t.get()); - - if (state == PR_UNJOINABLE_THREAD) { - t->thread().detach(); - } - - return t.release(); - } catch (...) { - return nullptr; - } -} - -PRStatus PR_JoinThread(PRThread* thread) { - try { - thread->thread().join(); - - delete thread; - - return PR_SUCCESS; - } catch (...) { - return PR_FAILURE; +#define MONGO_MOZ_UNIMPLEMENTED(ReturnType, funcName, ...) \ + ReturnType funcName(__VA_ARGS__) { \ + MOZ_CRASH(#funcName " unimplemented"); \ } -} - -PRThread* PR_GetCurrentThread() { - return kCurrentThread; -} - -PRStatus PR_SetCurrentThreadName(const char* name) { - mongo::setThreadName(name); - - return PR_SUCCESS; -} -namespace { +MONGO_MOZ_UNIMPLEMENTED(void, mongo::mozjs::PR_BindThread, PRThread*); +MONGO_MOZ_UNIMPLEMENTED(PRThread*, mongo::mozjs::PR_CreateFakeThread); +MONGO_MOZ_UNIMPLEMENTED(void, mongo::mozjs::PR_DestroyFakeThread, PRThread*); -const size_t MaxTLSKeyCount = 32; -size_t gTLSKeyCount; -thread_local std::array gTLSArray; +MONGO_MOZ_UNIMPLEMENTED(PRThread*, + PR_CreateThread, + PRThreadType, + void (*)(void*), + void*, + PRThreadPriority, + PRThreadScope, + PRThreadState, + uint32_t); -} // namespace +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_JoinThread, PRThread*); -PRStatus PR_NewThreadPrivateIndex(unsigned* newIndex, PRThreadPrivateDTOR destructor) { - /* - * We only call PR_NewThreadPrivateIndex from the main thread, so there's no - * need to lock the table of TLS keys. - */ - MOZ_ASSERT(gTLSKeyCount + 1 < MaxTLSKeyCount); +MONGO_MOZ_UNIMPLEMENTED(PRThread*, PR_GetCurrentThread); - *newIndex = gTLSKeyCount; - gTLSKeyCount++; +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_SetCurrentThreadName, const char*); - return PR_SUCCESS; -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_NewThreadPrivateIndex, unsigned*, PRThreadPrivateDTOR); -PRStatus PR_SetThreadPrivate(unsigned index, void* priv) { - if (index >= gTLSKeyCount) - return PR_FAILURE; +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_SetThreadPrivate, unsigned, void*); - gTLSArray[index] = priv; +MONGO_MOZ_UNIMPLEMENTED(void*, PR_GetThreadPrivate, unsigned); - return PR_SUCCESS; -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_CallOnce, PRCallOnceType*, PRCallOnceFN); -void* PR_GetThreadPrivate(unsigned index) { - if (index >= gTLSKeyCount) - return nullptr; +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_CallOnceWithArg, PRCallOnceType*, PRCallOnceWithArgFN, void*); - return gTLSArray[index]; -} +MONGO_MOZ_UNIMPLEMENTED(PRLock*, PR_NewLock); -PRStatus PR_CallOnce(PRCallOnceType* once, PRCallOnceFN func) { - MOZ_CRASH("PR_CallOnce unimplemented"); -} +MONGO_MOZ_UNIMPLEMENTED(void, PR_DestroyLock, PRLock*); -PRStatus PR_CallOnceWithArg(PRCallOnceType* once, PRCallOnceWithArgFN func, void* arg) { - MOZ_CRASH("PR_CallOnceWithArg unimplemented"); -} +MONGO_MOZ_UNIMPLEMENTED(void, PR_Lock, PRLock*); -class nspr::Lock { - mongo::Mutex mutex_; +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_Unlock, PRLock*); -public: - Lock() {} - mongo::Mutex& mutex() { - return mutex_; - } -}; - -PRLock* PR_NewLock() { - return js_new(); -} +MONGO_MOZ_UNIMPLEMENTED(PRCondVar*, PR_NewCondVar, PRLock*); -void PR_DestroyLock(PRLock* lock) { - js_delete(lock); -} +MONGO_MOZ_UNIMPLEMENTED(void, PR_DestroyCondVar, PRCondVar*); -void PR_Lock(PRLock* lock) { - lock->mutex().lock(); -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_NotifyCondVar, PRCondVar*); -PRStatus PR_Unlock(PRLock* lock) { - lock->mutex().unlock(); +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_NotifyAllCondVar, PRCondVar*); - return PR_SUCCESS; -} +MONGO_MOZ_UNIMPLEMENTED(uint32_t, PR_MillisecondsToInterval, uint32_t); -class nspr::CondVar { - mongo::stdx::condition_variable cond_; - nspr::Lock* lock_; +MONGO_MOZ_UNIMPLEMENTED(uint32_t, PR_MicrosecondsToInterval, uint32_t); -public: - CondVar(nspr::Lock* lock) : lock_(lock) {} - mongo::stdx::condition_variable& cond() { - return cond_; - } - nspr::Lock* lock() { - return lock_; - } -}; +MONGO_MOZ_UNIMPLEMENTED(uint32_t, PR_TicksPerSecond); -PRCondVar* PR_NewCondVar(PRLock* lock) { - return js_new(lock); -} - -void PR_DestroyCondVar(PRCondVar* cvar) { - js_delete(cvar); -} - -PRStatus PR_NotifyCondVar(PRCondVar* cvar) { - cvar->cond().notify_one(); - - return PR_SUCCESS; -} - -PRStatus PR_NotifyAllCondVar(PRCondVar* cvar) { - cvar->cond().notify_all(); - - return PR_SUCCESS; -} - -uint32_t PR_MillisecondsToInterval(uint32_t milli) { - return milli; -} - -uint32_t PR_MicrosecondsToInterval(uint32_t micro) { - return (micro + 999) / 1000; -} - -static const uint64_t TicksPerSecond = 1000; -static const uint64_t NanoSecondsInSeconds = 1000000000; -static const uint64_t MicroSecondsInSeconds = 1000000; - -uint32_t PR_TicksPerSecond() { - return TicksPerSecond; -} - -PRStatus PR_WaitCondVar(PRCondVar* cvar, uint32_t timeout) { - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - try { - mongo::stdx::unique_lock lk(cvar->lock()->mutex(), - mongo::stdx::adopt_lock_t()); - - cvar->cond().wait(lk); - lk.release(); - - return PR_SUCCESS; - } catch (...) { - return PR_FAILURE; - } - } else { - try { - mongo::stdx::unique_lock lk(cvar->lock()->mutex(), - mongo::stdx::adopt_lock_t()); - - cvar->cond().wait_for(lk, mongo::Microseconds(timeout).toSystemDuration()); - lk.release(); - - return PR_SUCCESS; - } catch (...) { - return PR_FAILURE; - } - } -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_WaitCondVar, PRCondVar*, uint32_t); -int32_t PR_FileDesc2NativeHandle(PRFileDesc* fd) { - MOZ_CRASH("PR_FileDesc2NativeHandle"); -} +MONGO_MOZ_UNIMPLEMENTED(int32_t, PR_FileDesc2NativeHandle, PRFileDesc*); -PRStatus PR_GetOpenFileInfo(PRFileDesc* fd, PRFileInfo* info) { - MOZ_CRASH("PR_GetOpenFileInfo"); -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_GetOpenFileInfo, PRFileDesc*, PRFileInfo*); -int32_t PR_Seek(PRFileDesc* fd, int32_t offset, PRSeekWhence whence) { - MOZ_CRASH("PR_Seek"); -} +MONGO_MOZ_UNIMPLEMENTED(int32_t, PR_Seek, PRFileDesc*, int32_t, PRSeekWhence); -PRFileMap* PR_CreateFileMap(PRFileDesc* fd, int64_t size, PRFileMapProtect prot) { - MOZ_CRASH("PR_CreateFileMap"); -} +MONGO_MOZ_UNIMPLEMENTED(PRFileMap*, PR_CreateFileMap, PRFileDesc*, int64_t, PRFileMapProtect); -void* PR_MemMap(PRFileMap* fmap, int64_t offset, uint32_t len) { - MOZ_CRASH("PR_MemMap"); -} +MONGO_MOZ_UNIMPLEMENTED(void*, PR_MemMap, PRFileMap*, int64_t, uint32_t); -PRStatus PR_MemUnmap(void* addr, uint32_t len) { - MOZ_CRASH("PR_MemUnmap"); -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_MemUnmap, void*, uint32_t); -PRStatus PR_CloseFileMap(PRFileMap* fmap) { - MOZ_CRASH("PR_CloseFileMap"); -} +MONGO_MOZ_UNIMPLEMENTED(PRStatus, PR_CloseFileMap, PRFileMap*); diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp index c78115b5ae2..0e03c5573af 100644 --- a/src/mongo/scripting/mozjs/implscope.cpp +++ b/src/mongo/scripting/mozjs/implscope.cpp @@ -151,7 +151,7 @@ void MozJSImplScope::kill() { // If we are on the right thread, in the middle of an operation, and we have a registered // opCtx, then we should check the opCtx for interrupts. - if (_mr._thread.get() == PR_GetCurrentThread() && _inOp > 0 && _opCtx) { + if (_mr._thread.get_id() == stdx::this_thread::get_id() && _inOp > 0 && _opCtx) { _killStatus = _opCtx->checkForInterruptNoAssert(); } @@ -274,23 +274,6 @@ MozJSImplScope::MozRuntime::MozRuntime(const MozJSScriptEngine* engine) { size_t mallocMemoryLimit = 1024ul * 1024 * jsHeapLimit; mongo::sm::reset(mallocMemoryLimit); - // If this runtime isn't running on an NSPR thread, then it is - // running on a mongo thread. In that case, we need to insert a - // fake NSPR thread so that the SM runtime can call PR functions - // without falling over. - auto thread = PR_GetCurrentThread(); - if (!thread) { - _thread = std::unique_ptr>( - PR_CreateFakeThread(), [](PRThread* ptr) { - if (ptr) { - invariant(PR_GetCurrentThread() == ptr); - PR_DestroyFakeThread(ptr); - PR_BindThread(nullptr); - } - }); - PR_BindThread(_thread.get()); - } - { stdx::unique_lock lk(gRuntimeCreationMutex); diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h index 79bd262dae9..d3b5d590fc2 100644 --- a/src/mongo/scripting/mozjs/implscope.h +++ b/src/mongo/scripting/mozjs/implscope.h @@ -379,7 +379,7 @@ private: public: MozRuntime(const MozJSScriptEngine* engine); - std::unique_ptr> _thread; + std::thread _thread; std::unique_ptr> _runtime; std::unique_ptr> _context; }; diff --git a/src/mongo/scripting/mozjs/jsthread.cpp b/src/mongo/scripting/mozjs/jsthread.cpp index 3b6580abcf6..fcd3549d21e 100644 --- a/src/mongo/scripting/mozjs/jsthread.cpp +++ b/src/mongo/scripting/mozjs/jsthread.cpp @@ -106,24 +106,14 @@ public: void start() { uassert(ErrorCodes::JSInterpreterFailure, "Thread already started", !_started); - // Despite calling PR_CreateThread, we're actually using our own - // implementation of PosixNSPR.cpp in this directory. So these threads - // are actually hosted on top of stdx::threads and most of the flags - // don't matter. - _thread = PR_CreateThread(PR_USER_THREAD, - JSThread::run, - &_jsthread, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0); + _thread = stdx::thread(JSThread::run, &_jsthread); _started = true; } void join() { uassert(ErrorCodes::JSInterpreterFailure, "Thread not running", _started && !_done); - PR_JoinThread(_thread); + _thread.join(); _done = true; uassertStatusOK(_sharedData->getErrorStatus()); @@ -211,7 +201,7 @@ private: bool _started; bool _done; - PRThread* _thread = nullptr; + stdx::thread _thread; std::shared_ptr _sharedData; JSThread _jsthread; }; diff --git a/src/mongo/scripting/mozjs/proxyscope.cpp b/src/mongo/scripting/mozjs/proxyscope.cpp index fc3a38d0927..e4fce4699f4 100644 --- a/src/mongo/scripting/mozjs/proxyscope.cpp +++ b/src/mongo/scripting/mozjs/proxyscope.cpp @@ -51,17 +51,7 @@ MozJSProxyScope::MozJSProxyScope(MozJSScriptEngine* engine) _mutex(), _state(State::Idle), _status(Status::OK()), - // Despite calling PR_CreateThread, we're actually using our own - // implementation of PosixNSPR.cpp in this directory. So these threads - // are actually hosted on top of stdx::threads and most of the flags - // don't matter. - _thread(PR_CreateThread(PR_USER_THREAD, - implThread, - this, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0)) { + _thread(implThread, this) { // Test the child on startup to make sure it's awake and that the // implementation scope sucessfully constructed. try { @@ -266,7 +256,7 @@ void MozJSProxyScope::run(Closure&& closure) { // methods on it from there. If we're on the same thread, it's safe to // simply call back in, so let's do that. - if (_thread == PR_GetCurrentThread()) { + if (_thread.get_id() == stdx::this_thread::get_id()) { return closure(); } @@ -331,7 +321,7 @@ void MozJSProxyScope::shutdownThread() { _implCondvar.notify_one(); - PR_JoinThread(_thread); + _thread.join(); } /** @@ -346,9 +336,7 @@ void MozJSProxyScope::shutdownThread() { * Shutdown: Shutdown -> _ * break out of the loop and return. */ -void MozJSProxyScope::implThread(void* arg) { - auto proxy = static_cast(arg); - +void MozJSProxyScope::implThread(MozJSProxyScope* proxy) { if (hasGlobalServiceContext()) Client::initThread("js"); diff --git a/src/mongo/scripting/mozjs/proxyscope.h b/src/mongo/scripting/mozjs/proxyscope.h index d0d4c5a3423..8d3269c7474 100644 --- a/src/mongo/scripting/mozjs/proxyscope.h +++ b/src/mongo/scripting/mozjs/proxyscope.h @@ -186,7 +186,7 @@ private: void runOnImplThread(unique_function f); void shutdownThread(); - static void implThread(void* proxy); + static void implThread(MozJSProxyScope* proxy); MozJSScriptEngine* const _engine; MozJSImplScope* _implScope; @@ -203,7 +203,7 @@ private: stdx::condition_variable _proxyCondvar; stdx::condition_variable _implCondvar; - PRThread* _thread; + stdx::thread _thread; }; } // namespace mozjs -- cgit v1.2.1