diff --git a/arangod/RestServer/DatabaseFeature.cpp b/arangod/RestServer/DatabaseFeature.cpp index 53ef7b07ef..bf6a0ad7e8 100644 --- a/arangod/RestServer/DatabaseFeature.cpp +++ b/arangod/RestServer/DatabaseFeature.cpp @@ -225,6 +225,10 @@ void DatabaseFeature::start() { } void DatabaseFeature::stop() { +#warning TODO: we can get rid of this once V8DealerFeature is started AFTER the DatabaseFeature + // get rid of references in V8 + V8DealerFeature::DEALER->shutdownContexts(); + // clear the query registery _server->_queryRegistry = nullptr; diff --git a/arangod/V8Server/V8DealerFeature.cpp b/arangod/V8Server/V8DealerFeature.cpp index eeecc6521a..651cc53ecf 100644 --- a/arangod/V8Server/V8DealerFeature.cpp +++ b/arangod/V8Server/V8DealerFeature.cpp @@ -200,80 +200,7 @@ void V8DealerFeature::start() { } void V8DealerFeature::stop() { - _stopping = true; - - // wait for all contexts to finish - { - CONDITION_LOCKER(guard, _contextCondition); - guard.broadcast(); - - for (size_t n = 0; n < 10 * 5; ++n) { - if (_busyContexts.empty()) { - LOG(DEBUG) << "no busy V8 contexts"; - break; - } - - LOG(DEBUG) << "waiting for busy V8 contexts (" << _busyContexts.size() - << ") to finish "; - - guard.wait(100000); - } - } - - // send all busy contexts a termate signal - { - CONDITION_LOCKER(guard, _contextCondition); - - for (auto& it : _busyContexts) { - LOG(WARN) << "sending termination signal to V8 context"; - v8::V8::TerminateExecution(it->_isolate); - } - } - - // wait for one minute - { - CONDITION_LOCKER(guard, _contextCondition); - - for (size_t n = 0; n < 10 * 60; ++n) { - if (_busyContexts.empty()) { - break; - } - - guard.wait(100000); - } - } - - // stop GC thread - if (_gcThread != nullptr) { - LOG(DEBUG) << "Waiting for GC Thread to finish action"; - _gcThread->beginShutdown(); - - // wait until garbage collector thread is done - while (!_gcFinished) { - usleep(10000); - } - - LOG(DEBUG) << "Commanding GC Thread to terminate"; - } - - // shutdown all instances - { - CONDITION_LOCKER(guard, _contextCondition); - - for (size_t i = 0; i < _nrContexts; ++i) { - shutdownV8Instance(i); - } - - delete[] _contexts; - } - - LOG(DEBUG) << "Shutting down V8"; - - // delete GC thread after all action threads have been stopped - if (_gcThread != nullptr) { - delete _gcThread; - } - + shutdownContexts(); DEALER = nullptr; } @@ -723,6 +650,82 @@ void V8DealerFeature::updateContexts( } } +void V8DealerFeature::shutdownContexts() { + _stopping = true; + + // wait for all contexts to finish + { + CONDITION_LOCKER(guard, _contextCondition); + guard.broadcast(); + + for (size_t n = 0; n < 10 * 5; ++n) { + if (_busyContexts.empty()) { + LOG(DEBUG) << "no busy V8 contexts"; + break; + } + + LOG(DEBUG) << "waiting for busy V8 contexts (" << _busyContexts.size() + << ") to finish "; + + guard.wait(100000); + } + } + + // send all busy contexts a termate signal + { + CONDITION_LOCKER(guard, _contextCondition); + + for (auto& it : _busyContexts) { + LOG(WARN) << "sending termination signal to V8 context"; + v8::V8::TerminateExecution(it->_isolate); + } + } + + // wait for one minute + { + CONDITION_LOCKER(guard, _contextCondition); + + for (size_t n = 0; n < 10 * 60; ++n) { + if (_busyContexts.empty()) { + break; + } + + guard.wait(100000); + } + } + + // stop GC thread + if (_gcThread != nullptr) { + LOG(DEBUG) << "Waiting for GC Thread to finish action"; + _gcThread->beginShutdown(); + + // wait until garbage collector thread is done + while (!_gcFinished) { + usleep(10000); + } + + LOG(DEBUG) << "Commanding GC Thread to terminate"; + } + + // shutdown all instances + { + CONDITION_LOCKER(guard, _contextCondition); + + for (size_t i = 0; i < _nrContexts; ++i) { + shutdownV8Instance(i); + } + + delete[] _contexts; + } + + LOG(DEBUG) << "Shutting down V8"; + + // delete GC thread after all action threads have been stopped + if (_gcThread != nullptr) { + delete _gcThread; + } +} + V8Context* V8DealerFeature::pickFreeContextForGc() { int const n = (int)_freeContexts.size(); diff --git a/arangod/V8Server/V8DealerFeature.h b/arangod/V8Server/V8DealerFeature.h index 9b1efff902..74a85e190a 100644 --- a/arangod/V8Server/V8DealerFeature.h +++ b/arangod/V8Server/V8DealerFeature.h @@ -71,6 +71,8 @@ class V8DealerFeature final : public application_features::ApplicationFeature { std::function, size_t)>, TRI_vocbase_t*); + void shutdownContexts(); + private: V8Context* pickFreeContextForGc(); void initializeContext(size_t);