ApplicationV8::V8Context* ApplicationV8::enterContext () { CONDITION_LOCKER(guard, _contextCondition); while (_freeContexts.empty() && ! _stopping) { LOGGER_DEBUG("waiting for unused V8 context"); guard.wait(); } // in case we are in the shutdown phase, do not enter a context! // the context might have been deleted by the shutdown if (_stopping) { return 0; } LOGGER_TRACE("found unused V8 context"); V8Context* context = _freeContexts.back(); assert(context != 0); assert(context->_isolate != 0); _freeContexts.pop_back(); _busyContexts.insert(context); context->_locker = new v8::Locker(context->_isolate); context->_isolate->Enter(); context->_context->Enter(); context->handleGlobalContextMethods(); return context; }
ApplicationV8::V8Context* ApplicationV8::enterContext (TRI_vocbase_s* vocbase, triagens::rest::HttpRequest* request, bool initialise, bool allowUseDatabase) { CONDITION_LOCKER(guard, _contextCondition); while (_freeContexts.empty() && ! _stopping) { LOG_DEBUG("waiting for unused V8 context"); guard.wait(); } // in case we are in the shutdown phase, do not enter a context! // the context might have been deleted by the shutdown if (_stopping) { return 0; } LOG_TRACE("found unused V8 context"); V8Context* context = _freeContexts.back(); assert(context != 0); assert(context->_isolate != 0); _freeContexts.pop_back(); _busyContexts.insert(context); context->_locker = new v8::Locker(context->_isolate); context->_isolate->Enter(); context->_context->Enter(); // set the current database v8::HandleScope scope; TRI_v8_global_t* v8g = (TRI_v8_global_t*) context->_isolate->GetData(); v8g->_vocbase = vocbase; v8g->_allowUseDatabase = allowUseDatabase; LOG_TRACE("entering V8 context %d", (int) context->_id); context->handleGlobalContextMethods(); if (_developmentMode && ! initialise) { v8::HandleScope scope; TRI_ExecuteJavaScriptString(context->_context, v8::String::New("require(\"internal\").resetEngine()"), v8::String::New("global context method"), false); } return context; }
ApplicationV8::V8Context* ApplicationV8::enterContext (std::string const& name, TRI_vocbase_t* vocbase, bool allowUseDatabase) { CONDITION_LOCKER(guard, _contextCondition); while (_freeContexts[name].empty() && ! _stopping) { LOG_DEBUG("waiting for unused V8 context"); auto currentThread = triagens::rest::DispatcherThread::currentDispatcherThread; if (currentThread != nullptr) { triagens::rest::DispatcherThread::currentDispatcherThread->blockThread(); } guard.wait(); if (currentThread != nullptr) { triagens::rest::DispatcherThread::currentDispatcherThread->unblockThread(); } } // in case we are in the shutdown phase, do not enter a context! // the context might have been deleted by the shutdown if (_stopping) { return nullptr; } LOG_TRACE("found unused V8 context"); TRI_ASSERT(! _freeContexts[name].empty()); V8Context* context = _freeContexts[name].back(); TRI_ASSERT(context != nullptr); auto isolate = context->isolate; TRI_ASSERT(isolate != nullptr); _freeContexts[name].pop_back(); _busyContexts[name].insert(context); context->_locker = new v8::Locker(isolate); context->isolate->Enter(); v8::HandleScope scope(isolate); auto localContext = v8::Local<v8::Context>::New(isolate, context->_context); localContext->Enter(); { v8::Context::Scope contextScope(localContext); TRI_ASSERT(context->_locker->IsLocked(isolate)); TRI_ASSERT(v8::Locker::IsLocked(isolate)); TRI_GET_GLOBALS(); // initialize the context data v8g->_query = nullptr; v8g->_vocbase = vocbase; v8g->_allowUseDatabase = allowUseDatabase; TRI_UseVocBase(vocbase); LOG_TRACE("entering V8 context %d", (int) context->_id); context->handleGlobalContextMethods(); } return context; }