Ejemplo n.º 1
0
 virtual void performTask(ScriptExecutionContext *context)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(context->isWorkerGlobalScope());
     WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context);
     // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed.
     workerGlobalScope->clearScript();
 }
double WorkerPerformance::now(ExecutionContext* context) const
{
    ASSERT(context);
    ASSERT(context->isWorkerGlobalScope());
    WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
    return 1000.0 * (monotonicallyIncreasingTime() - workerGlobalScope->timeOrigin());
}
Ejemplo n.º 3
0
    virtual void performTask(ScriptExecutionContext *context)
    {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);

#if ENABLE(SQL_DATABASE)
        // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below?
        DatabaseTaskSynchronizer cleanupSync;
        DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync);
#endif

        workerGlobalScope->stopActiveDOMObjects();

        workerGlobalScope->notifyObserversOfStop();

        // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
        // which become dangling once Heap is destroyed.
        workerGlobalScope->removeAllEventListeners();

#if ENABLE(SQL_DATABASE)
        // We wait for the database thread to clean up all its stuff so that we
        // can do more stringent leak checks as we exit.
        cleanupSync.waitForTaskCompletion();
#endif

        // Stick a shutdown command at the end of the queue, so that we deal
        // with all the cleanup tasks the databases post first.
        workerGlobalScope->postTask(WorkerThreadShutdownFinishTask::create());
    }
Ejemplo n.º 4
0
bool DatabaseObserver::canEstablishDatabase(ExecutionContext* executionContext, const String& name, const String& displayName, unsigned long estimatedSize)
{
    ASSERT(executionContext->isContextThread());
    ASSERT(executionContext->isDocument() || executionContext->isWorkerGlobalScope());
    if (executionContext->isDocument()) {
        Document* document = toDocument(executionContext);
        WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
        if (!webFrame)
            return false;
        WebViewImpl* webView = webFrame->viewImpl();
        if (!webView)
            return false;
        if (webView->permissionClient())
            return webView->permissionClient()->allowDatabase(webFrame, name, displayName, estimatedSize);
    } else {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(executionContext);
        WorkerPermissionClient* permissionClient = WorkerPermissionClient::from(workerGlobalScope);
        if (permissionClient->proxy())
            return permissionClient->allowDatabase(name, displayName, estimatedSize);

        // FIXME: Deprecate this bridge code when PermissionClientProxy is
        // implemented by the embedder.
        WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerGlobalScope->thread()->workerLoaderProxy().toWebWorkerBase());
        WebView* view = webWorker->view();
        if (!view)
            return false;
        return allowDatabaseForWorker(view->mainFrame(), name, displayName, estimatedSize);
    }

    return true;
}
Ejemplo n.º 5
0
    static ThrottlingController* from(ExecutionContext* context)
    {
        if (!context)
            return 0;

        if (context->isDocument()) {
            Document* document = toDocument(context);
            if (!document->frame())
                return 0;

            ThrottlingController* controller = static_cast<ThrottlingController*>(WillBeHeapSupplement<LocalFrame>::from(document->frame(), supplementName()));
            if (controller)
                return controller;

            controller = new ThrottlingController();
            WillBeHeapSupplement<LocalFrame>::provideTo(*document->frame(), supplementName(), adoptPtrWillBeNoop(controller));
            return controller;
        }
        ASSERT(!isMainThread());
        ASSERT(context->isWorkerGlobalScope());
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
        ThrottlingController* controller = static_cast<ThrottlingController*>(WillBeHeapSupplement<WorkerClients>::from(workerGlobalScope->clients(), supplementName()));
        if (controller)
            return controller;

        controller = new ThrottlingController();
        WillBeHeapSupplement<WorkerClients>::provideTo(*workerGlobalScope->clients(), supplementName(), adoptPtrWillBeNoop(controller));
        return controller;
    }
Ejemplo n.º 6
0
PassRefPtr<WebSocketChannel> WebSocketChannel::create(ExecutionContext* context, WebSocketChannelClient* client)
{
    ASSERT(context);
    ASSERT(client);

    String sourceURL;
    unsigned lineNumber = 0;
    RefPtr<ScriptCallStack> callStack = createScriptCallStack(1, true);
    if (callStack && callStack->size()) {
        sourceURL = callStack->at(0).sourceURL();
        lineNumber = callStack->at(0).lineNumber();
    }

    if (context->isWorkerGlobalScope()) {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
        WorkerRunLoop& runLoop = workerGlobalScope->thread()->runLoop();
        String mode = webSocketChannelMode + String::number(runLoop.createUniqueId());
        return WorkerThreadableWebSocketChannel::create(workerGlobalScope, client, mode, sourceURL, lineNumber);
    }

    Document* document = toDocument(context);
    Settings* settings = document->settings();
    if (settings && settings->experimentalWebSocketEnabled()) {
        // FIXME: Create and return an "experimental" WebSocketChannel instead of a MainThreadWebSocketChannel.
        return MainThreadWebSocketChannel::create(document, client, sourceURL, lineNumber);
    }
    return MainThreadWebSocketChannel::create(document, client, sourceURL, lineNumber);
}
bool DatabaseObserver::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize)
{
    ASSERT(scriptExecutionContext->isContextThread());
    ASSERT(scriptExecutionContext->isDocument() || scriptExecutionContext->isWorkerGlobalScope());
    if (scriptExecutionContext->isDocument()) {
        Document* document = toDocument(scriptExecutionContext);
        WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
        if (!webFrame)
            return false;
        WebViewImpl* webView = webFrame->viewImpl();
        if (!webView)
            return false;
        if (webView->permissionClient())
            return webView->permissionClient()->allowDatabase(webFrame, name, displayName, estimatedSize);
    } else {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(scriptExecutionContext);
        WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerGlobalScope->thread()->workerLoaderProxy().toWebWorkerBase());
        WebView* view = webWorker->view();
        if (!view)
            return false;
        return allowDatabaseForWorker(view->mainFrame(), name, displayName, estimatedSize);
    }

    return true;
}
Ejemplo n.º 8
0
void WorkerDebuggerGlobalScope::Dump(JSContext* aCx,
                                     const Optional<nsAString>& aString) const {
  WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
  if (scope) {
    scope->Dump(aString);
  }
}
Ejemplo n.º 9
0
 virtual void performTask(ScriptExecutionContext *context)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(context->isWorkerGlobalScope());
     WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context);
     // Notify parent that this context is closed. Parent is responsible for calling WorkerThread::stop().
     workerGlobalScope->thread()->workerReportingProxy().workerGlobalScopeClosed();
 }
void WebSharedWorkerImpl::connectTask(PassOwnPtr<WebMessagePortChannel> channel, ExecutionContext* context)
{
    // Wrap the passed-in channel in a MessagePort, and send it off via a connect event.
    MessagePort* port = MessagePort::create(*context);
    port->entangle(channel);
    WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
    ASSERT_WITH_SECURITY_IMPLICATION(workerGlobalScope->isSharedWorkerGlobalScope());
    workerGlobalScope->dispatchEvent(createConnectEvent(port));
}
Ejemplo n.º 11
0
void MemoryCache::removeURLFromCache(ExecutionContext* context, const KURL& url)
{
    if (context->isWorkerGlobalScope()) {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
        workerGlobalScope->thread()->workerLoaderProxy().postTaskToLoader(createCallbackTask(&removeURLFromCacheInternal, url));
        return;
    }
    removeURLFromCacheInternal(context, url);
}
Ejemplo n.º 12
0
void WebSharedWorkerImpl::connectTask(WebMessagePortChannelUniquePtr channel,
                                      ExecutionContext* context) {
  // Wrap the passed-in channel in a MessagePort, and send it off via a connect
  // event.
  MessagePort* port = MessagePort::create(*context);
  port->entangle(std::move(channel));
  WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
  SECURITY_DCHECK(workerGlobalScope->isSharedWorkerGlobalScope());
  workerGlobalScope->dispatchEvent(createConnectEvent(port));
}
Ejemplo n.º 13
0
void WorkerDebuggerGlobalScope::GetGlobal(JSContext* aCx,
                                          JS::MutableHandle<JSObject*> aGlobal,
                                          ErrorResult& aRv) {
  WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
  if (!scope) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  aGlobal.set(scope->GetWrapper());
}
 virtual void performTask(ScriptExecutionContext* scriptContext)
 {
     RefPtr<MessagePort> port = MessagePort::create(*scriptContext);
     port->entangle(m_channel.release());
     ASSERT_WITH_SECURITY_IMPLICATION(scriptContext->isWorkerGlobalScope());
     WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(scriptContext);
     // Since close() stops the thread event loop, this should not ever get called while closing.
     ASSERT(!workerGlobalScope->isClosing());
     ASSERT_WITH_SECURITY_IMPLICATION(workerGlobalScope->isSharedWorkerGlobalScope());
     workerGlobalScope->dispatchEvent(createConnectEvent(port));
 }
Ejemplo n.º 15
0
 SharedWorkerConnectTask(MessagePortChannel* channel)
     : ScriptExecutionContext::Task([=] (ScriptExecutionContext& context) {
         RefPtr<MessagePort> port = MessagePort::create(context);
         port->entangle(std::unique_ptr<MessagePortChannel>(channel));
         ASSERT_WITH_SECURITY_IMPLICATION(context.isWorkerGlobalScope());
         WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(&context);
         // Since close() stops the thread event loop, this should not ever get called while closing.
         ASSERT(!workerGlobalScope->isClosing());
         ASSERT_WITH_SECURITY_IMPLICATION(workerGlobalScope->isSharedWorkerGlobalScope());
         workerGlobalScope->dispatchEvent(createConnectEvent(port));
     })
 {
 }
Ejemplo n.º 16
0
WorkerScriptController* WorkerScriptController::controllerForContext(v8::Isolate* isolate)
{
    // Happens on frame destruction, check otherwise GetCurrent() will crash.
    if (!isolate || !isolate->InContext())
        return 0;
    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    v8::Handle<v8::Object> global = context->Global();
    global = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(isolate, WorkerWorld));
    // Return 0 if the current executing context is not the worker context.
    if (global.IsEmpty())
        return 0;
    WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(global);
    return workerGlobalScope->script();
}
Ejemplo n.º 17
0
void WorkerDebuggerGlobalScope::RetrieveConsoleEvents(
    JSContext* aCx, nsTArray<JS::Value>& aEvents, ErrorResult& aRv) {
  WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
  if (!scope) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  RefPtr<Console> console = scope->GetConsole(aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  console->RetrieveConsoleEvents(aCx, aEvents, aRv);
}
WorkerGlobalScopeIndexedDatabase* WorkerGlobalScopeIndexedDatabase::from(ScriptExecutionContext* context)
{
    WorkerGlobalScopeIndexedDatabase* supplement = static_cast<WorkerGlobalScopeIndexedDatabase*>(Supplement<ScriptExecutionContext>::from(context, supplementName()));
    if (!supplement) {
        String databaseDirectoryIdentifier;
        WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context);
        const GroupSettings* groupSettings = workerGlobalScope->groupSettings();
        if (groupSettings)
            databaseDirectoryIdentifier = groupSettings->indexedDBDatabasePath();

        supplement = new WorkerGlobalScopeIndexedDatabase(databaseDirectoryIdentifier);
        provideTo(context, supplementName(), adoptPtr(supplement));
    }
    return supplement;
}
void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& workerGlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
    WebWaitableEvent* shutdownEvent =
        workerGlobalScope.thread()->shutdownEvent();
    OwnPtr<WebWaitableEvent> loaderDone =
        adoptPtr(Platform::current()->createWaitableEvent());

    Vector<WebWaitableEvent*> events;
    events.append(shutdownEvent);
    events.append(loaderDone.get());

    RefPtr<ThreadableLoaderClientWrapper> clientWrapper(ThreadableLoaderClientWrapper::create(&client));
    OwnPtr<WorkerLoaderClientBridgeSyncHelper> clientBridge(WorkerLoaderClientBridgeSyncHelper::create(clientWrapper.get(), loaderDone.release()));

    // This must be valid while loader is around.
    WorkerLoaderClientBridgeSyncHelper* clientBridgePtr = clientBridge.get();

    RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerGlobalScope, clientWrapper, clientBridge.release(), request, options, resourceLoaderOptions);

    WebWaitableEvent* signalled;
    {
        SafePointScope scope(ThreadState::HeapPointersOnStack);
        signalled = Platform::current()->waitMultipleEvents(events);
    }
    if (signalled == shutdownEvent) {
        loader->cancel();
        return;
    }

    clientBridgePtr->run();
}
WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope& workerGlobalScope, PassRefPtr<ThreadableLoaderClientWrapper> clientWrapper, PassOwnPtr<ThreadableLoaderClient> clientBridge, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
    : m_workerGlobalScope(&workerGlobalScope)
    , m_workerClientWrapper(clientWrapper)
    , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, clientBridge, workerGlobalScope.thread()->workerLoaderProxy(), request, options, resourceLoaderOptions, workerGlobalScope.referrerPolicy(), workerGlobalScope.url().strippedForUseAsReferrer())))
{
    m_workerClientWrapper->setResourceTimingClient(this);
}
Ejemplo n.º 21
0
void WorkerGlobalScope::close()
{
    if (m_closing)
        return;

    // Let current script run to completion but prevent future script evaluations.
    // After m_closing is set, all the tasks in the queue continue to be fetched but only
    // tasks with isCleanupTask()==true will be executed.
    m_closing = true;
    postTask({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context) {
        ASSERT_WITH_SECURITY_IMPLICATION(context.isWorkerGlobalScope());
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(&context);
        // Notify parent that this context is closed. Parent is responsible for calling WorkerThread::stop().
        workerGlobalScope->thread().workerReportingProxy().workerGlobalScopeClosed();
    } });
}
Ejemplo n.º 22
0
void WorkerDebuggerGlobalScope::SetConsoleEventHandler(JSContext* aCx,
                                                       AnyCallback* aHandler,
                                                       ErrorResult& aRv) {
  WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
  if (!scope) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  RefPtr<Console> console = scope->GetConsole(aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  console->SetConsoleEventHandler(aHandler);
}
static void setTimeoutOrInterval(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot)
{
    WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(info.Holder());
    ASSERT(workerGlobalScope);

    int argumentCount = info.Length();
    if (argumentCount < 1)
        return;

    v8::Handle<v8::Value> function = info[0];

    WorkerScriptController* script = workerGlobalScope->script();
    if (!script)
        return;

    ScriptState* scriptState = ScriptState::current(info.GetIsolate());
    OwnPtr<ScheduledAction> action;
    if (function->IsString()) {
        if (ContentSecurityPolicy* policy = workerGlobalScope->contentSecurityPolicy()) {
            if (!policy->allowEval()) {
                v8SetReturnValue(info, 0);
                return;
            }
        }
        action = adoptPtr(new ScheduledAction(scriptState, toCoreString(function.As<v8::String>()), workerGlobalScope->url(), info.GetIsolate()));
    } else if (function->IsFunction()) {
        size_t paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
        OwnPtr<v8::Local<v8::Value>[]> params;
        if (paramCount > 0) {
            params = adoptArrayPtr(new v8::Local<v8::Value>[paramCount]);
            for (size_t i = 0; i < paramCount; ++i)
                params[i] = info[i+2];
        }
        // ScheduledAction takes ownership of actual params and releases them in its destructor.
        action = adoptPtr(new ScheduledAction(scriptState, v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
    } else
        return;

    int32_t timeout = argumentCount >= 2 ? info[1]->Int32Value() : 0;
    int timerId;
    if (singleShot)
        timerId = DOMWindowTimers::setTimeout(*workerGlobalScope, action.release(), timeout);
    else
        timerId = DOMWindowTimers::setInterval(*workerGlobalScope, action.release(), timeout);

    v8SetReturnValue(info, timerId);
}
Ejemplo n.º 24
0
bool IDBFactoryBackendProxy::allowIndexedDB(ExecutionContext* context, const String& name, const WebSecurityOrigin& origin, PassRefPtr<IDBCallbacks> callbacks)
{
    bool allowed;
    ASSERT_WITH_SECURITY_IMPLICATION(context->isDocument() || context->isWorkerGlobalScope());
    if (context->isDocument()) {
        Document* document = toDocument(context);
        WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
        WebViewImpl* webView = webFrame->viewImpl();
        // FIXME: webView->permissionClient() returns 0 in test_shell and content_shell http://crbug.com/137269
        allowed = !webView->permissionClient() || webView->permissionClient()->allowIndexedDB(webFrame, name, origin);
    } else {
        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
        WorkerPermissionClient* permissionClient = WorkerPermissionClient::from(workerGlobalScope);
        if (permissionClient->proxy()) {
            allowed = permissionClient->allowIndexedDB(name);
            if (!allowed)
                callbacks->onError(WebIDBDatabaseError(UnknownError, "The user denied permission to access the database."));

            return allowed;
        }

        // FIXME: Deprecate this bridge code when PermissionClientProxy is
        // implemented by the embedder.
        WebWorkerBase* webWorkerBase = static_cast<WebWorkerBase*>(workerGlobalScope->thread()->workerLoaderProxy().toWebWorkerBase());
        WorkerRunLoop& runLoop = workerGlobalScope->thread()->runLoop();

        String mode = allowIndexedDBMode;
        mode.append(String::number(runLoop.createUniqueId()));
        RefPtr<AllowIndexedDBMainThreadBridge> bridge = AllowIndexedDBMainThreadBridge::create(workerGlobalScope, webWorkerBase, mode, name);

        // Either the bridge returns, or the queue gets terminated.
        if (runLoop.runInMode(workerGlobalScope, mode) == MessageQueueTerminated) {
            bridge->cancel();
            return false;
        }
        allowed = bridge->result();
    }

    if (!allowed)
        callbacks->onError(WebIDBDatabaseError(UnknownError, "The user denied permission to access the database."));

    return allowed;
}
Ejemplo n.º 25
0
static bool isAllowed(ScriptState* scriptState, ExecutionContext* executionContext, bool isEval)
{
    if (executionContext->isDocument()) {
        Document* document = static_cast<Document*>(executionContext);
        if (isEval && !document->contentSecurityPolicy()->allowEval(scriptState, ContentSecurityPolicy::SendReport, ContentSecurityPolicy::WillNotThrowException))
            return false;
        return true;
    }
    if (executionContext->isWorkerGlobalScope()) {
        WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(executionContext);
        if (!workerGlobalScope->script())
            return false;
        ContentSecurityPolicy* policy = workerGlobalScope->contentSecurityPolicy();
        if (isEval && policy && !policy->allowEval(scriptState, ContentSecurityPolicy::SendReport, ContentSecurityPolicy::WillNotThrowException))
            return false;
        return true;
    }
    ASSERT_NOT_REACHED();
    return false;
}
static void openFileSystem(ScriptExecutionContext* context, const String& basePath, FileSystemType type, long long size, bool create, PassOwnPtr<AsyncFileSystemCallbacks> callbacks, FileSystemSynchronousType synchronousType)
{
    ASSERT(context);
    ASSERT(type != FileSystemTypeIsolated);
    if (type == FileSystemTypeIsolated)
        return;

    KURL url = context->url();
    if (url.hasFragmentIdentifier())
        url.removeFragmentIdentifier();
    url.setQuery(String());
    url.setPath("/");
    StringBuilder builder;
    builder.append("filesystem:");
    builder.append(url.string());
    builder.append(fileSystemTypeString(type));
    KURL rootURL = context->completeURL(builder.toString());
    ASSERT(rootURL.isValid());

    // TODO: Ask user for file system permission.

    if (context->isDocument()) {
        int playerId = 0;
        Page* page = static_cast<Document*>(context)->page();
        if (page)
            playerId = page->chrome().client()->platformPageClient()->playerID();
        AsyncFileSystemBlackBerry::openFileSystem(rootURL, basePath, context->securityOrigin()->databaseIdentifier(), type, size, create, playerId, callbacks);
    } else {
#if ENABLE(WORKERS)
        WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context);
        String mode = openFileSystemMode;
        mode.append(String::number(workerGlobalScope->thread()->runLoop().createUniqueId()));
        WorkerAsyncFileSystemBlackBerry::openFileSystem(workerGlobalScope, rootURL, mode, basePath, context->securityOrigin()->databaseIdentifier(), type, size, create, callbacks);
        if (synchronousType == SynchronousFileSystem)
            workerGlobalScope->thread()->runLoop().runInMode(workerGlobalScope, mode);
#else
        ASSERT_NOT_REACHED();
#endif
    }
}
void LocalFileSystem::deleteFileSystem(ScriptExecutionContext* context, FileSystemType type, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
    ASSERT(context);
    ASSERT(type != FileSystemTypeIsolated);
    if (type == FileSystemTypeIsolated)
        return;

    // TODO: Ask user for file system permission.

    if (context->isDocument())
        AsyncFileSystemBlackBerry::deleteFileSystem(fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, callbacks);
    else {
#if ENABLE(WORKERS)
        WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context);
        String mode = deleteFileSystemMode;
        mode.append(String::number(workerGlobalScope->thread()->runLoop().createUniqueId()));
        WorkerAsyncFileSystemBlackBerry::deleteFileSystem(workerGlobalScope, mode, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, callbacks);
#else
        ASSERT_NOT_REACHED();
#endif
    }
}
Ejemplo n.º 28
0
void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& workerGlobalScope, ResourceRequest&& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
{
    WorkerRunLoop& runLoop = workerGlobalScope.thread().runLoop();

    // Create a unique mode just for this synchronous resource load.
    String mode = loadResourceSynchronouslyMode;
    mode.append(String::number(runLoop.createUniqueId()));

    RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerGlobalScope, client, mode, WTFMove(request), options, String());
    MessageQueueWaitResult result = MessageQueueMessageReceived;
    while (!loader->done() && result != MessageQueueTerminated)
        result = runLoop.runInMode(&workerGlobalScope, mode);

    if (!loader->done() && result == MessageQueueTerminated)
        loader->cancel();
}
PassRefPtrWillBeRawPtr<DatabaseSync> WorkerGlobalScopeWebDatabase::openDatabaseSync(WorkerGlobalScope& context, const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassOwnPtr<DatabaseCallback> creationCallback, ExceptionState& exceptionState)
{
    DatabaseManager& dbManager = DatabaseManager::manager();
    RefPtrWillBeRawPtr<DatabaseSync> database = nullptr;
    DatabaseError error =  DatabaseError::None;
    if (RuntimeEnabledFeatures::databaseEnabled() && context.securityOrigin()->canAccessDatabase()) {
        String errorMessage;
        database = dbManager.openDatabaseSync(&context, name, version, displayName, estimatedSize, creationCallback, error, errorMessage);
        ASSERT(database || error != DatabaseError::None);
        if (error != DatabaseError::None)
            DatabaseManager::throwExceptionForDatabaseError(error, errorMessage, exceptionState);
    } else {
        exceptionState.throwSecurityError("Access to the WebDatabase API is denied in this context.");
    }

    return database.release();
}
Ejemplo n.º 30
0
void WorkerThread::stop()
{
    // Mutex protection is necessary because stop() can be called before the context is fully created.
    MutexLocker lock(m_threadCreationMutex);

    // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever.
    if (m_workerGlobalScope) {
        m_workerGlobalScope->script()->scheduleExecutionTermination();

#if ENABLE(SQL_DATABASE)
        DatabaseManager::manager().interruptAllDatabasesForContext(m_workerGlobalScope.get());
#endif
        m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext* context ) {
            WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);

#if ENABLE(SQL_DATABASE)
            // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below?
            DatabaseTaskSynchronizer cleanupSync;
            DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync);
#endif

            workerGlobalScope->stopActiveDOMObjects();

            workerGlobalScope->notifyObserversOfStop();

            // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
            // which become dangling once Heap is destroyed.
            workerGlobalScope->removeAllEventListeners();

#if ENABLE(SQL_DATABASE)
            // We wait for the database thread to clean up all its stuff so that we
            // can do more stringent leak checks as we exit.
            cleanupSync.waitForTaskCompletion();
#endif

            // Stick a shutdown command at the end of the queue, so that we deal
            // with all the cleanup tasks the databases post first.
            workerGlobalScope->postTask({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext* context) {
                WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
                // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed.
                workerGlobalScope->clearScript();
            } });

        } });
        return;
    }
    m_runLoop.terminate();
}