void WorkerFileSystemCallbacksBridge::postCreateFileToMainThread(WebFileSystem* fileSystem, const KURL& path, bool exclusive, const String& mode)
{
    dispatchTaskToMainThread(
        createCallbackTask(&createFileOnMainThread,
                           AllowCrossThreadAccess(fileSystem), path, exclusive,
                           this, mode));
}
void WorkerFileSystemCallbacksBridge::postCopyToMainThread(WebFileSystem* fileSystem, const KURL& sourcePath, const KURL& destinationPath, const String& mode)
{
    dispatchTaskToMainThread(
        createCallbackTask(&copyOnMainThread,
                           AllowCrossThreadAccess(fileSystem), sourcePath, destinationPath,
                           this, mode));
}
void WorkerFileSystemCallbacksBridge::postOpenFileSystemToMainThread(WebCommonWorkerClient* commonClient, WebFileSystem::Type type, long long size, bool create, const String& mode)
{
    dispatchTaskToMainThread(
        createCallbackTask(&openFileSystemOnMainThread,
                           AllowCrossThreadAccess(commonClient), type, size, create,
                           this, mode));
}
Esempio n. 4
0
void AsyncFileStream::startOnFileThread()
{
    // FIXME: It is not correct to check m_client from a secondary thread - stop() could be racing with this check.
    if (!m_client)
        return;
    m_stream->start();
    callOnMainThread(didStart, AllowCrossThreadAccess(this));
}
DataConsumerHandleTestUtil::Thread::Thread(const char* name, InitializationPolicy initializationPolicy)
    : m_thread(WebThreadSupportingGC::create(name))
    , m_initializationPolicy(initializationPolicy)
    , m_waitableEvent(adoptPtr(Platform::current()->createWaitableEvent()))
{
    m_thread->postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&Thread::initialize, AllowCrossThreadAccess(this))));
    m_waitableEvent->wait();
}
void WorkerFileSystemCallbacksBridge::postCreateSnapshotFileToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode)
{
    ASSERT(fileSystem);
    dispatchTaskToMainThread(
        createCallbackTask(&createSnapshotFileOnMainThread,
                           AllowCrossThreadAccess(fileSystem),
                           path, this, mode));
}
void WorkerFileSystemCallbacksBridge::postDirectoryExistsToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode)
{
    ASSERT(fileSystem);
    dispatchTaskToMainThread(
        createCallbackTask(&directoryExistsOnMainThread,
                           AllowCrossThreadAccess(fileSystem), path,
                           this, mode));
}
void WorkerFileSystemCallbacksBridge::postRemoveRecursivelyToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode)
{
    ASSERT(fileSystem);
    dispatchTaskToMainThread(
        createCallbackTask(&removeRecursivelyOnMainThread,
                           AllowCrossThreadAccess(fileSystem), path,
                           this, mode));
}
void WebWorkerClientImpl::confirmMessageFromWorkerObject(bool hasPendingActivity)
{
    // unconfirmed_message_count_ can only be updated on the thread where it's
    // accessed.  Otherwise there are race conditions with v8's garbage
    // collection.
    m_scriptExecutionContext->postTask(createCallbackTask(&confirmMessageFromWorkerObjectTask,
                                                          AllowCrossThreadAccess(this)));
}
void WorkerThreadableLoader::MainThreadBridge::destroy()
{
    // Ensure that no more client callbacks are done in the worker context's thread.
    clearClientWrapper();

    // "delete this" and m_mainThreadLoader::deref() on the worker object's thread.
    m_loaderProxy.postTaskToLoader(
        createCallbackTask(&MainThreadBridge::mainThreadDestroy, AllowCrossThreadAccess(this)));
}
Esempio n. 11
0
void WebSharedWorkerImpl::postExceptionToWorkerObject(const String& errorMessage,
                                                      int lineNumber,
                                                      const String& sourceURL)
{
    WebWorkerBase::dispatchTaskToMainThread(
        createCallbackTask(&postExceptionTask, AllowCrossThreadAccess(this),
                           errorMessage, lineNumber,
                           sourceURL));
}
Esempio n. 12
0
void WorkerThreadableWebSocketChannel::Bridge::disconnect()
{
    clearClientWrapper();
    if (m_peer) {
        Peer* peer = m_peer;
        m_peer = 0;
        m_loaderProxy.postTaskToLoader(createCallbackTask(&mainThreadDestroy, AllowCrossThreadAccess(peer)));
    }
    m_workerContext = 0;
}
void HTMLParserThread::postTask(PassOwnPtr<CrossThreadClosure> closure)
{
    ASSERT(isMainThread());
    if (!m_thread) {
        m_thread = WebThreadSupportingGC::create("HTMLParserThread");
        postTask(threadSafeBind(&HTMLParserThread::setupHTMLParserThread, AllowCrossThreadAccess(this)));
    }

    m_thread->postTask(BLINK_FROM_HERE, closure);
}
Esempio n. 14
0
void WebWorkerClientImpl::workerObjectDestroyed()
{
    if (isMainThread()) {
        m_webWorker->workerObjectDestroyed();
        m_worker = 0;
    }
    // Even if this is called on the main thread, there could be a queued task for
    // this object, so don't delete it right away.
    WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&workerObjectDestroyedTask,
                                                               AllowCrossThreadAccess(this)));
}
Esempio n. 15
0
void WebWorkerBase::postConsoleMessageToWorkerObject(MessageSource source,
                                                     MessageType type,
                                                     MessageLevel level,
                                                     const String& message,
                                                     int lineNumber,
                                                     const String& sourceURL)
{
    dispatchTaskToMainThread(createCallbackTask(&postConsoleMessageTask, AllowCrossThreadAccess(this),
                                                source, type, level,
                                                message, lineNumber, sourceURL));
}
Esempio n. 16
0
bool CCThreadProxy::initializeLayerRenderer()
{
    TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
    // Make a blocking call to initializeLayerRendererOnImplThread. The results of that call
    // are pushed into the initializeSucceeded and capabilities local variables.
    CCCompletionEvent completion;
    bool initializeSucceeded = false;
    LayerRendererCapabilities capabilities;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnImplThread,
                                                       AllowCrossThreadAccess(&completion),
                                                       AllowCrossThreadAccess(&initializeSucceeded),
                                                       AllowCrossThreadAccess(&capabilities)));
    completion.wait();

    if (initializeSucceeded) {
        m_layerRendererInitialized = true;
        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
    }
    return initializeSucceeded;
}
WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, WorkerLoaderProxy& loaderProxy, const String& taskMode,
                                                           const ResourceRequest& request, const ThreadableLoaderOptions& options, const String& outgoingReferrer)
    : m_workerClientWrapper(workerClientWrapper)
    , m_loaderProxy(loaderProxy)
    , m_taskMode(taskMode.isolatedCopy())
{
    ASSERT(m_workerClientWrapper.get());
    m_loaderProxy.postTaskToLoader(
        createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, 
                           AllowCrossThreadAccess(this), request, options, outgoingReferrer));
}
void WorkerThreadableWebSocketChannel::Bridge::initialize()
{
    ASSERT(!m_peer);
    setMethodNotCompleted();
    Ref<Bridge> protect(*this);
    m_loaderProxy.postTaskToLoader(CrossThreadTask(&Bridge::mainThreadInitialize, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode));
    waitForMethodCompletion();
    // m_peer may be null when the nested runloop exited before a peer has created.
    m_peer = m_workerClientWrapper->peer();
    if (!m_peer)
        m_workerClientWrapper->setFailedWebSocketChannelCreation();
}
Esempio n. 19
0
void WebWorkerClientImpl::terminateWorkerContext()
{
    if (m_askedToTerminate)
        return;
    m_askedToTerminate = true;
    if (!isMainThread()) {
        WebWorkerBase::dispatchTaskToMainThread(
            createCallbackTask(&terminateWorkerContextTask, AllowCrossThreadAccess(this)));
        return;
    }
    m_webWorker->terminateWorkerContext();
}
void WorkerThreadableLoader::MainThreadBridge::cancel()
{
    m_loaderProxy.postTaskToLoader(
        createCallbackTask(&MainThreadBridge::mainThreadCancel, AllowCrossThreadAccess(this)));
    ThreadableLoaderClientWrapper* clientWrapper = m_workerClientWrapper.get();
    if (!clientWrapper->done()) {
        // If the client hasn't reached a termination state, then transition it by sending a cancellation error.
        // Note: no more client callbacks will be done after this method -- the clearClientWrapper() call ensures that.
        ResourceError error(String(), 0, String(), String());
        error.setIsCancellation(true);
        clientWrapper->didFail(error);
    }
    clearClientWrapper();
}
Esempio n. 21
0
WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode, const KURL& url, const String& protocol)
    : m_workerClientWrapper(workerClientWrapper)
    , m_workerContext(workerContext)
    , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
    , m_taskMode(taskMode)
    , m_peer(0)
{
    ASSERT(m_workerClientWrapper.get());
    setMethodNotCompleted();
    m_loaderProxy.postTaskToLoader(
        createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel,
                           AllowCrossThreadAccess(this), m_workerClientWrapper, m_taskMode, url, protocol));
    waitForMethodCompletion();
    ASSERT(m_peer);
}
Esempio n. 22
0
bool CCThreadProxy::initializeLayerRenderer()
{
    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D();
    if (!context)
        return false;
    ASSERT(context->hasOneRef());

    // Leak the context pointer so we can transfer ownership of it to the other side...
    GraphicsContext3D* contextPtr = context.release().leakRef();
    ASSERT(contextPtr->hasOneRef());

    // Make a blocking call to initializeLayerRendererOnCCThread. The results of that call
    // are pushed into the initializeSucceeded and capabilities local variables.
    CCCompletionEvent completion;
    bool initializeSucceeded;
    LayerRendererCapabilities capabilities;
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnCCThread,
                                          AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&initializeSucceeded), AllowCrossThreadAccess(&capabilities)));
    completion.wait();

    if (initializeSucceeded)
        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
    return initializeSucceeded;
}
Esempio n. 23
0
bool CCThreadProxy::recreateContext()
{
    TRACE_EVENT0("cc", "CCThreadProxy::recreateContext");
    ASSERT(isMainThread());

    // Try to create the context.
    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
    if (!context)
        return false;
    if (CCLayerTreeHost::needsFilterContext())
        if (!SharedGraphicsContext3D::createForImplThread())
            return false;

    ASSERT(context->hasOneRef());

    // Leak the context pointer so we can transfer ownership of it to the other side...
    GraphicsContext3D* contextPtr = context.release().leakRef();
    ASSERT(contextPtr->hasOneRef());

    // Make a blocking call to recreateContextOnImplThread. The results of that
    // call are pushed into the recreateSucceeded and capabilities local
    // variables.
    CCCompletionEvent completion;
    bool recreateSucceeded = false;
    LayerRendererCapabilities capabilities;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::recreateContextOnImplThread,
                                                       AllowCrossThreadAccess(&completion),
                                                       AllowCrossThreadAccess(contextPtr),
                                                       AllowCrossThreadAccess(&recreateSucceeded),
                                                       AllowCrossThreadAccess(&capabilities)));
    completion.wait();

    if (recreateSucceeded)
        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
    return recreateSucceeded;
}
Esempio n. 24
0
bool CCThreadProxy::initializeContext()
{
    TRACE_EVENT("CCThreadProxy::initializeContext", this, 0);
    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
    if (!context)
        return false;
    ASSERT(context->hasOneRef());

    // Leak the context pointer so we can transfer ownership of it to the other side...
    GraphicsContext3D* contextPtr = context.release().leakRef();
    ASSERT(contextPtr->hasOneRef());

    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeContextOnImplThread,
                                                       AllowCrossThreadAccess(contextPtr)));
    return true;
}
Esempio n. 25
0
WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(
    PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper,
    PassOwnPtr<ThreadableLoaderClient> clientBridge,
    WorkerLoaderProxy& loaderProxy,
    const ResourceRequest& request,
    const ThreadableLoaderOptions& options,
    const ResourceLoaderOptions& resourceLoaderOptions,
    const String& outgoingReferrer)
    : m_clientBridge(clientBridge)
    , m_workerClientWrapper(workerClientWrapper)
    , m_loaderProxy(loaderProxy)
{
    ASSERT(m_workerClientWrapper.get());
    ASSERT(m_clientBridge.get());
    m_loaderProxy.postTaskToLoader(
        createCrossThreadTask(&MainThreadBridge::mainThreadCreateLoader, AllowCrossThreadAccess(this), request, options, resourceLoaderOptions, outgoingReferrer));
}
Esempio n. 26
0
void WebWorkerClientImpl::startWorkerContext(const KURL& scriptURL,
                                             const String& userAgent,
                                             const String& sourceCode)
{
    // Worker.terminate() could be called from JS before the context is started.
    if (m_askedToTerminate)
        return;
    if (!isMainThread()) {
        WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(
            &startWorkerContextTask,
            AllowCrossThreadAccess(this),
            scriptURL.string(),
            userAgent,
            sourceCode));
        return;
    }
    m_webWorker->startWorkerContext(scriptURL, userAgent, sourceCode);
}
Esempio n. 27
0
void WebWorkerImpl::postMessageToWorkerContext(const WebString& message,
                                               const WebMessagePortChannelArray& webChannels)
{
    OwnPtr<MessagePortChannelArray> channels;
    if (webChannels.size()) {
        channels = new MessagePortChannelArray(webChannels.size());
        for (size_t i = 0; i < webChannels.size(); ++i) {
            RefPtr<PlatformMessagePortChannel> platform_channel =
                PlatformMessagePortChannel::create(webChannels[i]);
            webChannels[i]->setClient(platform_channel.get());
            (*channels)[i] = MessagePortChannel::create(platform_channel);
        }
    }

    workerThread()->runLoop().postTask(
        createCallbackTask(&postMessageToWorkerContextTask,
                           AllowCrossThreadAccess(this), String(message), channels.release()));
}
Esempio n. 28
0
void CCThreadProxy::beginFrameAndCommit(double frameBeginTime)
{
    ASSERT(isMainThread());
    if (!m_layerTreeHost)
        return;

    TRACE_EVENT("CCThreadProxy::requestFrameAndCommit", this, 0);
    {
        TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0);
        m_layerTreeHost->animateAndLayout(frameBeginTime);
    }

    m_commitPending = false;

    // Blocking call to CCThreadProxy::performCommit
    CCCompletionEvent completion;
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion)));
    completion.wait();
}
Esempio n. 29
0
void WebWorkerClientImpl::postExceptionToWorkerObject(const WebString& errorMessage,
                                                      int lineNumber,
                                                      const WebString& sourceURL)
{
    if (currentThread() != m_workerThreadId) {
        m_scriptExecutionContext->postTask(createCallbackTask(&postExceptionToWorkerObjectTask,
                                                              AllowCrossThreadAccess(this),
                                                              String(errorMessage),
                                                              lineNumber,
                                                              String(sourceURL)));
        return;
    }

    bool unhandled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage,
                                                                sourceURL,
                                                                lineNumber));
    if (unhandled)
        m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL, 0);
}
TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
{
    setFrameStatus(ImageFrame::FramePartial);

    char buffer[100 * 100 * 4];
    m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
    EXPECT_EQ(1, m_decodeRequestCount);
    EXPECT_EQ(0, m_decodersDestroyed);

    // LocalFrame can now be decoded completely.
    setFrameStatus(ImageFrame::FrameComplete);
    addNewData();
    OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("DecodeThread"));
    thread->postTask(FROM_HERE, new Task(threadSafeBind(&decodeThreadMain, AllowCrossThreadAccess(m_generator.get()))));
    thread.clear();
    EXPECT_EQ(2, m_decodeRequestCount);
    EXPECT_EQ(1, m_decodersDestroyed);

    // Decoder created again.
    m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
    EXPECT_EQ(3, m_decodeRequestCount);
}