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(©OnMainThread, 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)); }
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))); }
void WebSharedWorkerImpl::postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL) { WebWorkerBase::dispatchTaskToMainThread( createCallbackTask(&postExceptionTask, AllowCrossThreadAccess(this), errorMessage, lineNumber, sourceURL)); }
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); }
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))); }
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)); }
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(); }
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(); }
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); }
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; }
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; }
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; }
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)); }
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); }
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())); }
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(); }
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); }