| /* |
| * Copyright (C) 2010, 2012 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| #include "WorkerFileSystemCallbacksBridge.h" |
| |
| #include "WebCommonWorkerClient.h" |
| #include "WebFileSystemCallbacksImpl.h" |
| #include "WebWorkerBase.h" |
| #include "bindings/v8/WorkerScriptController.h" |
| #include "core/dom/CrossThreadTask.h" |
| #include "core/platform/network/BlobData.h" |
| #include "core/workers/WorkerGlobalScope.h" |
| #include "core/workers/WorkerLoaderProxy.h" |
| #include "core/workers/WorkerThread.h" |
| #include "public/platform/WebFileInfo.h" |
| #include "public/platform/WebFileSystemEntry.h" |
| #include "public/platform/WebString.h" |
| #include "public/platform/WebURL.h" |
| #include "weborigin/KURL.h" |
| #include "wtf/MainThread.h" |
| #include "wtf/Threading.h" |
| #include "wtf/UnusedParam.h" |
| |
| namespace WebCore { |
| |
| template<> struct CrossThreadCopierBase<false, false, WebKit::WebFileInfo> { |
| typedef WebKit::WebFileInfo Type; |
| static Type copy(const WebKit::WebFileInfo& info) |
| { |
| // Perform per-field copy to make sure we don't do any (unexpected) non-thread safe copy here. |
| struct WebKit::WebFileInfo newInfo; |
| newInfo.modificationTime = info.modificationTime; |
| newInfo.length = info.length; |
| newInfo.type = info.type; |
| newInfo.platformPath.assign(info.platformPath); |
| return newInfo; |
| } |
| }; |
| |
| template<> struct CrossThreadCopierBase<false, false, WebKit::WebVector<WebKit::WebFileSystemEntry> > { |
| typedef WebKit::WebVector<WebKit::WebFileSystemEntry> Type; |
| static Type copy(const WebKit::WebVector<WebKit::WebFileSystemEntry>& entries) |
| { |
| WebKit::WebVector<WebKit::WebFileSystemEntry> newEntries(entries.size()); |
| for (size_t i = 0; i < entries.size(); ++i) { |
| String name = entries[i].name; |
| newEntries[i].isDirectory = entries[i].isDirectory; |
| newEntries[i].name = name.isolatedCopy(); |
| } |
| return newEntries; |
| } |
| }; |
| |
| } |
| |
| using namespace WebCore; |
| |
| namespace WebKit { |
| |
| // FileSystemCallbacks that are to be dispatched on the main thread. |
| class MainThreadFileSystemCallbacks : public WebFileSystemCallbacks { |
| public: |
| // Callbacks are self-destructed and we always return leaked pointer here. |
| static MainThreadFileSystemCallbacks* createLeakedPtr(PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| OwnPtr<MainThreadFileSystemCallbacks> callbacks = adoptPtr(new MainThreadFileSystemCallbacks(bridge, mode)); |
| return callbacks.leakPtr(); |
| } |
| |
| virtual ~MainThreadFileSystemCallbacks() |
| { |
| } |
| |
| virtual void didOpenFileSystem(const WebString& name, const WebURL& rootURL) |
| { |
| m_bridge->didOpenFileSystemOnMainThread(name, rootURL, m_mode); |
| delete this; |
| } |
| |
| virtual void didFail(WebFileError error) |
| { |
| m_bridge->didFailOnMainThread(error, m_mode); |
| delete this; |
| } |
| |
| virtual void didSucceed() |
| { |
| m_bridge->didSucceedOnMainThread(m_mode); |
| delete this; |
| } |
| |
| virtual void didReadMetadata(const WebFileInfo& info) |
| { |
| m_bridge->didReadMetadataOnMainThread(info, m_mode); |
| delete this; |
| } |
| |
| virtual void didCreateSnapshotFile(const WebFileInfo& info) |
| { |
| // It's important to create a BlobDataHandle that refers to the platform file path prior |
| // to return from this method so the underlying file will not be deleted. |
| OwnPtr<BlobData> blobData = BlobData::create(); |
| blobData->appendFile(info.platformPath); |
| RefPtr<BlobDataHandle> snapshotBlob = BlobDataHandle::create(blobData.release(), info.length); |
| m_bridge->didCreateSnapshotFileOnMainThread(info, m_mode, snapshotBlob); |
| delete this; |
| } |
| |
| virtual void didReadDirectory(const WebVector<WebFileSystemEntry>& entries, bool hasMore) |
| { |
| m_bridge->didReadDirectoryOnMainThread(entries, hasMore, m_mode); |
| delete this; |
| } |
| |
| virtual bool shouldBlockUntilCompletion() const |
| { |
| return false; |
| } |
| |
| private: |
| MainThreadFileSystemCallbacks(PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| : m_bridge(bridge) |
| , m_mode(mode) |
| { |
| ASSERT(m_bridge); |
| } |
| |
| RefPtr<WorkerFileSystemCallbacksBridge> m_bridge; |
| const String m_mode; |
| }; |
| |
| // Observes the worker context. By keeping this separate, it is easier to verify |
| // that it only gets deleted on the worker context thread which is verified by ~Observer. |
| class WorkerFileSystemContextObserver : public WebCore::WorkerGlobalScope::Observer { |
| public: |
| static PassOwnPtr<WorkerFileSystemContextObserver> create(WorkerGlobalScope* context, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge) |
| { |
| return adoptPtr(new WorkerFileSystemContextObserver(context, bridge)); |
| } |
| |
| // WorkerGlobalScope::Observer method. |
| virtual void notifyStop() |
| { |
| m_bridge->stop(); |
| } |
| |
| private: |
| WorkerFileSystemContextObserver(WorkerGlobalScope* context, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge) |
| : WebCore::WorkerGlobalScope::Observer(context) |
| , m_bridge(bridge) |
| { |
| } |
| |
| RefPtr<WorkerFileSystemCallbacksBridge> m_bridge; |
| }; |
| |
| void WorkerFileSystemCallbacksBridge::stop() |
| { |
| ASSERT(m_workerGlobalScope->isContextThread()); |
| { |
| MutexLocker locker(m_loaderProxyMutex); |
| m_workerLoaderProxy = 0; |
| } |
| |
| if (m_callbacksOnWorkerThread) |
| m_callbacksOnWorkerThread->didFail(WebFileErrorAbort); |
| |
| cleanUpAfterCallback(); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::cleanUpAfterCallback() |
| { |
| ASSERT(m_workerGlobalScope->isContextThread()); |
| |
| m_callbacksOnWorkerThread = 0; |
| if (m_workerGlobalScopeObserver) { |
| WorkerFileSystemContextObserver* observer = m_workerGlobalScopeObserver; |
| m_workerGlobalScopeObserver = 0; |
| // The next line may delete this. |
| delete observer; |
| } |
| } |
| |
| void WorkerFileSystemCallbacksBridge::postOpenFileSystemToMainThread(WebCommonWorkerClient* commonClient, WebFileSystemType type, long long size, bool create, const String& mode) |
| { |
| dispatchTaskToMainThread( |
| createCallbackTask(&openFileSystemOnMainThread, |
| AllowCrossThreadAccess(commonClient), type, size, create, |
| this, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::postMoveToMainThread(WebFileSystem* fileSystem, const KURL& sourcePath, const KURL& destinationPath, const String& mode) |
| { |
| dispatchTaskToMainThread( |
| createCallbackTask(&moveOnMainThread, |
| AllowCrossThreadAccess(fileSystem), sourcePath, destinationPath, |
| 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::postRemoveToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode) |
| { |
| ASSERT(fileSystem); |
| dispatchTaskToMainThread( |
| createCallbackTask(&removeOnMainThread, |
| 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 WorkerFileSystemCallbacksBridge::postReadMetadataToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode) |
| { |
| ASSERT(fileSystem); |
| dispatchTaskToMainThread( |
| createCallbackTask(&readMetadataOnMainThread, |
| AllowCrossThreadAccess(fileSystem), path, |
| this, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::postCreateFileToMainThread(WebFileSystem* fileSystem, const KURL& path, bool exclusive, const String& mode) |
| { |
| dispatchTaskToMainThread( |
| createCallbackTask(&createFileOnMainThread, |
| AllowCrossThreadAccess(fileSystem), path, exclusive, |
| this, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::postCreateDirectoryToMainThread(WebFileSystem* fileSystem, const KURL& path, bool exclusive, const String& mode) |
| { |
| ASSERT(fileSystem); |
| dispatchTaskToMainThread( |
| createCallbackTask(&createDirectoryOnMainThread, |
| AllowCrossThreadAccess(fileSystem), path, exclusive, |
| this, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::postFileExistsToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode) |
| { |
| ASSERT(fileSystem); |
| dispatchTaskToMainThread( |
| createCallbackTask(&fileExistsOnMainThread, |
| 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::postReadDirectoryToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode) |
| { |
| ASSERT(fileSystem); |
| dispatchTaskToMainThread( |
| createCallbackTask(&readDirectoryOnMainThread, |
| AllowCrossThreadAccess(fileSystem), path, |
| this, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::postCreateSnapshotFileToMainThread(WebFileSystem* fileSystem, const KURL& path, const String& mode) |
| { |
| ASSERT(fileSystem); |
| dispatchTaskToMainThread( |
| createCallbackTask(&createSnapshotFileOnMainThread, |
| AllowCrossThreadAccess(fileSystem), |
| path, this, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::openFileSystemOnMainThread(ScriptExecutionContext*, WebCommonWorkerClient* commonClient, WebFileSystemType type, long long size, bool create, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| if (!commonClient) |
| bridge->didFailOnMainThread(WebFileErrorAbort, mode); |
| else { |
| commonClient->openFileSystem(type, size, create, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| } |
| |
| void WorkerFileSystemCallbacksBridge::moveOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& sourcePath, const KURL& destinationPath, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->move(sourcePath, destinationPath, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::copyOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& sourcePath, const KURL& destinationPath, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->copy(sourcePath, destinationPath, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::removeOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->remove(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::removeRecursivelyOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->removeRecursively(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::readMetadataOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->readMetadata(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::createFileOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, bool exclusive, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->createFile(path, exclusive, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::createDirectoryOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, bool exclusive, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->createDirectory(path, exclusive, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::fileExistsOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->fileExists(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::directoryExistsOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->directoryExists(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::readDirectoryOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->readDirectory(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::createSnapshotFileOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem* fileSystem, const KURL& path, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode) |
| { |
| fileSystem->createSnapshotFileAndReadMetadata(path, MainThreadFileSystemCallbacks::createLeakedPtr(bridge, mode)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didFailOnMainThread(WebFileError error, const String& mode) |
| { |
| mayPostTaskToWorker(createCallbackTask(&didFailOnWorkerThread, this, error), mode); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didOpenFileSystemOnMainThread(const String& name, const KURL& rootURL, const String& mode) |
| { |
| mayPostTaskToWorker(createCallbackTask(&didOpenFileSystemOnWorkerThread, |
| this, name, rootURL), mode); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didSucceedOnMainThread(const String& mode) |
| { |
| mayPostTaskToWorker(createCallbackTask(&didSucceedOnWorkerThread, this), mode); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didReadMetadataOnMainThread(const WebFileInfo& info, const String& mode) |
| { |
| mayPostTaskToWorker(createCallbackTask(&didReadMetadataOnWorkerThread, this, info), mode); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didCreateSnapshotFileOnMainThread(const WebFileInfo& info, const String& mode, PassRefPtr<BlobDataHandle> snapshotBlob) |
| { |
| mayPostTaskToWorker(createCallbackTask(&didCreateSnapshotFileOnWorkerThread, this, info, snapshotBlob), mode); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didReadDirectoryOnMainThread(const WebVector<WebFileSystemEntry>& entries, bool hasMore, const String& mode) |
| { |
| mayPostTaskToWorker( |
| createCallbackTask(&didReadDirectoryOnWorkerThread, |
| this, entries, hasMore), mode); |
| } |
| |
| WorkerFileSystemCallbacksBridge::WorkerFileSystemCallbacksBridge(WebCore::WorkerLoaderProxy* workerLoaderProxy, ScriptExecutionContext* scriptExecutionContext, WebFileSystemCallbacksImpl* callbacks) |
| : m_workerLoaderProxy(workerLoaderProxy) |
| , m_workerGlobalScope(scriptExecutionContext) |
| , m_workerGlobalScopeObserver(WorkerFileSystemContextObserver::create(toWorkerGlobalScope(m_workerGlobalScope), this).leakPtr()) |
| , m_callbacksOnWorkerThread(callbacks) |
| { |
| ASSERT(m_workerGlobalScope->isContextThread()); |
| } |
| |
| WorkerFileSystemCallbacksBridge::~WorkerFileSystemCallbacksBridge() |
| { |
| ASSERT(!m_callbacksOnWorkerThread); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didFailOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, WebFileError error) |
| { |
| bridge->m_callbacksOnWorkerThread->didFail(error); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didOpenFileSystemOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& name, const KURL& rootURL) |
| { |
| bridge->m_callbacksOnWorkerThread->didOpenFileSystem(name, rootURL); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didSucceedOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge) |
| { |
| bridge->m_callbacksOnWorkerThread->didSucceed(); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didReadMetadataOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const WebFileInfo& info) |
| { |
| bridge->m_callbacksOnWorkerThread->didReadMetadata(info); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didCreateSnapshotFileOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const WebFileInfo& info, PassRefPtr<BlobDataHandle> snapshotBlob) |
| { |
| bridge->m_callbacksOnWorkerThread->didCreateSnapshotFile(info, snapshotBlob); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::didReadDirectoryOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const WebVector<WebFileSystemEntry>& entries, bool hasMore) |
| { |
| bridge->m_callbacksOnWorkerThread->didReadDirectory(entries, hasMore); |
| } |
| |
| |
| void WorkerFileSystemCallbacksBridge::runTaskOnMainThread(WebCore::ScriptExecutionContext* scriptExecutionContext, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, PassOwnPtr<WebCore::ScriptExecutionContext::Task> taskToRun) |
| { |
| ASSERT(isMainThread()); |
| taskToRun->performTask(scriptExecutionContext); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::runTaskOnWorkerThread(WebCore::ScriptExecutionContext* scriptExecutionContext, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, PassOwnPtr<WebCore::ScriptExecutionContext::Task> taskToRun) |
| { |
| if (!bridge->m_callbacksOnWorkerThread) |
| return; |
| ASSERT(bridge->m_workerGlobalScope->isContextThread()); |
| taskToRun->performTask(scriptExecutionContext); |
| |
| // taskToRun does the callback. |
| bridge->cleanUpAfterCallback(); |
| |
| // WorkerFileSystemCallbacksBridge may be deleted here when bridge goes out of scope. |
| } |
| |
| void WorkerFileSystemCallbacksBridge::dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task> task) |
| { |
| ASSERT(m_workerLoaderProxy); |
| ASSERT(m_workerGlobalScope->isContextThread()); |
| WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&runTaskOnMainThread, RefPtr<WorkerFileSystemCallbacksBridge>(this).release(), task)); |
| } |
| |
| void WorkerFileSystemCallbacksBridge::mayPostTaskToWorker(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode) |
| { |
| // Relies on its caller (MainThreadFileSystemCallbacks:did*) to keep WorkerFileSystemCallbacksBridge alive. |
| ASSERT(isMainThread()); |
| |
| MutexLocker locker(m_loaderProxyMutex); |
| if (m_workerLoaderProxy) |
| m_workerLoaderProxy->postTaskForModeToWorkerGlobalScope(createCallbackTask(&runTaskOnWorkerThread, this, task), mode); |
| } |
| |
| } // namespace WebCore |