1
0
Fork 0
This commit is contained in:
Frank Celler 2016-04-04 15:52:14 +02:00
parent de8059a97b
commit 31d477477e
3 changed files with 83 additions and 74 deletions

View File

@ -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;

View File

@ -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();

View File

@ -71,6 +71,8 @@ class V8DealerFeature final : public application_features::ApplicationFeature {
std::function<void(v8::Isolate*, v8::Handle<v8::Context>, size_t)>,
TRI_vocbase_t*);
void shutdownContexts();
private:
V8Context* pickFreeContextForGc();
void initializeContext(size_t);