[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

kinuko at chromium.org kinuko at chromium.org
Wed Dec 22 13:43:18 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 5434e1b63d69df09685b4c73f2b672bdd29549fc
Author: kinuko at chromium.org <kinuko at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Sep 24 00:46:01 2010 +0000

    2010-09-23  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Add Worker support for FileSystem API
            https://bugs.webkit.org/show_bug.cgi?id=45808
    
            Added WebWorkerBase::openFileSystem and WebCommonWorkerClient::
            openFileSystem to call in to the browser via Worker stub/proxy
            in the chromium.
    
            Also added WorkerFileSystemCallbacksBridge class that proxies
            requests and callbacks between from/to worker thread to/from the
            main thread.
    
            * public/WebCommonWorkerClient.h:
            (WebKit::WebCommonWorkerClient::openFileSystem): Added.
            * src/LocalFileSystemChromium.cpp:
            (WebCore::LocalFileSystem::localFileSystem): Added.
            (WebCore::LocalFileSystem::requestFileSystem): Added implementation
            for workers. In worker case this calls WebWorkerBase::openFileSystem.
            * src/WebWorkerBase.cpp:
            (WebKit::WebWorkerBase::openFileSystem): Added. This is called from
            LocalFileSystem::requestFileSystem on the worker thread and creates
            a bridge to call WebCommonWorkerClient::openFileSystem on the main
            thread.
            * src/WebWorkerBase.h:
            * src/WebWorkerClientImpl.h:
            (WebKit::WebWorkerClientImpl::openFileSystem): Added.
            * src/WorkerFileSystemCallbacksBridge.cpp: Added.
            * src/WorkerFileSystemCallbacksBridge.h: Added.
    2010-09-23  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Add Worker support for FileSystem API
            https://bugs.webkit.org/show_bug.cgi?id=45808
    
            Exposed requestFileSystem and Flags constructor on worker contexts.
    
            Also changed how to get the base path for Web file systems (in
            non-chromium ports) so that it works for workers too.
            This patch assumes each port calls
            LocalFileSystem::initializeLocalFileSystem() in its initialization
            phase.
    
            No new tests; tests will be added when we have complete implementation.
    
            * bindings/generic/RuntimeEnabledFeatures.cpp:
            (WebCore::RuntimeEnabledFeatures::fileSystemEnabled): Changed to
            reflect AsyncFileSystem::isAvailable
            * bindings/generic/RuntimeEnabledFeatures.h: Moved the implementation
            of fileSystemEnabled to .cpp.
            * fileapi/LocalFileSystem.cpp:
            (WebCore::LocalFileSystem::initializeLocalFileSystem): Added.
            (WebCore::LocalFileSystem::localFileSystem): Added.
            (WebCore::LocalFileSystem::fileSystemBasePath): Added.
            * fileapi/LocalFileSystem.h:
            (WebCore::LocalFileSystem::~LocalFileSystem): Removed. (As now it's
            going to be used as a singleton.)
            * page/DOMWindow.cpp:
            (WebCore::DOMWindow::requestFileSystem): Changed to use a singleton
            instance of LocalFileSystem.
            * page/SecurityOrigin.h:
            (WebCore::SecurityOrigin::canAccessFileSystem): Added.
            * page/Settings.cpp: Removed fileSystemRootPath method.
            * page/Settings.h: Removed fileSystemRootPath method.
            * platform/AsyncFileSystem.cpp:
            (WebCore::AsyncFileSystem::isAvailable): Added.
            * workers/WorkerContext.cpp:
            (WebCore::WorkerContext::requestFileSystem): Added to expose
            requestFileSystem method in worker contexts.
            (WebCore::WorkerContext::Observer): Added.
            (WebCore::WorkerContext::registerObserver): Added.
            (WebCore::WorkerContext::unregisterObserver): Added.
            (WebCore::WorkerContext::notifyObserversOfStop): Added.
            * workers/WorkerContext.h:
            * workers/WorkerContext.idl:
            * workers/WorkerThread.cpp:
            (WebCore::WorkerThreadShutdownStartTask::performTask): Modified to
            call workerContext->notifyObserversOfStop to notify worker observers
            of the worker thread termination.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@68222 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9b54389..30d7a9a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,55 @@
+2010-09-23  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Add Worker support for FileSystem API
+        https://bugs.webkit.org/show_bug.cgi?id=45808
+
+        Exposed requestFileSystem and Flags constructor on worker contexts.
+
+        Also changed how to get the base path for Web file systems (in
+        non-chromium ports) so that it works for workers too.
+        This patch assumes each port calls
+        LocalFileSystem::initializeLocalFileSystem() in its initialization
+        phase.
+
+        No new tests; tests will be added when we have complete implementation.
+
+        * bindings/generic/RuntimeEnabledFeatures.cpp:
+        (WebCore::RuntimeEnabledFeatures::fileSystemEnabled): Changed to
+        reflect AsyncFileSystem::isAvailable
+        * bindings/generic/RuntimeEnabledFeatures.h: Moved the implementation
+        of fileSystemEnabled to .cpp.
+        * fileapi/LocalFileSystem.cpp:
+        (WebCore::LocalFileSystem::initializeLocalFileSystem): Added.
+        (WebCore::LocalFileSystem::localFileSystem): Added.
+        (WebCore::LocalFileSystem::fileSystemBasePath): Added.
+        * fileapi/LocalFileSystem.h:
+        (WebCore::LocalFileSystem::~LocalFileSystem): Removed. (As now it's
+        going to be used as a singleton.)
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::requestFileSystem): Changed to use a singleton
+        instance of LocalFileSystem.
+        * page/SecurityOrigin.h:
+        (WebCore::SecurityOrigin::canAccessFileSystem): Added.
+        * page/Settings.cpp: Removed fileSystemRootPath method.
+        * page/Settings.h: Removed fileSystemRootPath method.
+        * platform/AsyncFileSystem.cpp:
+        (WebCore::AsyncFileSystem::isAvailable): Added.
+        * workers/WorkerContext.cpp:
+        (WebCore::WorkerContext::requestFileSystem): Added to expose
+        requestFileSystem method in worker contexts.
+        (WebCore::WorkerContext::Observer): Added.
+        (WebCore::WorkerContext::registerObserver): Added.
+        (WebCore::WorkerContext::unregisterObserver): Added.
+        (WebCore::WorkerContext::notifyObserversOfStop): Added.
+        * workers/WorkerContext.h:
+        * workers/WorkerContext.idl:
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThreadShutdownStartTask::performTask): Modified to
+        call workerContext->notifyObserversOfStop to notify worker observers
+        of the worker thread termination.
+
 2010-09-23  Matthew Delaney  <mdelaney at apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp b/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
index a15fd6d..9a96f22 100644
--- a/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
+++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
@@ -36,6 +36,10 @@
 #include "SharedWorkerRepository.h"
 #include "WebSocket.h"
 
+#if ENABLE(FILE_SYSTEM)
+#include "AsyncFileSystem.h"
+#endif
+
 namespace WebCore {
 
 bool RuntimeEnabledFeatures::isLocalStorageEnabled = true;
@@ -57,6 +61,11 @@ bool RuntimeEnabledFeatures::isXHRResponseBlobEnabled = false;
 
 #if ENABLE(FILE_SYSTEM)
 bool RuntimeEnabledFeatures::isFileSystemEnabled = false;
+
+bool RuntimeEnabledFeatures::fileSystemEnabled()
+{
+    return isFileSystemEnabled && AsyncFileSystem::isAvailable();
+}
 #endif
 
 #if ENABLE(VIDEO)
diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
index 91768b0..ba4a4fb 100644
--- a/WebCore/bindings/generic/RuntimeEnabledFeatures.h
+++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
@@ -148,7 +148,7 @@ public:
 #endif
 
 #if ENABLE(FILE_SYSTEM)
-    static bool fileSystemEnabled() { return isFileSystemEnabled; }
+    static bool fileSystemEnabled();
     static void setFileSystemEnabled(bool isEnabled) { isFileSystemEnabled = isEnabled; }
     static bool requestFileSystemEnabled() { return isFileSystemEnabled; }
 #endif
diff --git a/WebCore/fileapi/LocalFileSystem.cpp b/WebCore/fileapi/LocalFileSystem.cpp
index 59ec2a1..f826b71 100644
--- a/WebCore/fileapi/LocalFileSystem.cpp
+++ b/WebCore/fileapi/LocalFileSystem.cpp
@@ -50,9 +50,30 @@
 
 namespace WebCore {
 
-PassRefPtr<LocalFileSystem> LocalFileSystem::create(const String& basePath)
+LocalFileSystem* LocalFileSystem::s_instance = 0;
+
+void LocalFileSystem::initializeLocalFileSystem(const String& basePath)
+{
+    // FIXME: Should initialize the quota settings as well.
+    ASSERT(isMainThread());
+    ASSERT(!s_instance);
+    if (s_instance)
+        return;
+
+    OwnPtr<LocalFileSystem> localFileSystem = adoptPtr(new LocalFileSystem(basePath));
+    s_instance = localFileSystem.leakPtr();
+}
+
+LocalFileSystem& LocalFileSystem::localFileSystem()
+{
+    // initializeLocalFileSystem must be called prior calling this.
+    ASSERT(s_instance);
+    return *s_instance;
+}
+
+String LocalFileSystem::fileSystemBasePath() const
 {
-    return adoptRef(new LocalFileSystem(basePath));
+    return m_basePath;
 }
 
 static void openFileSystem(ScriptExecutionContext*, const String& basePath, const String& identifier, AsyncFileSystem::Type type, PassOwnPtr<FileSystemCallbacks> callbacks)
@@ -68,7 +89,7 @@ void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFi
     }
 
     // AsyncFileSystem::openFileSystem calls callbacks synchronously, so the method needs to be called asynchronously.
-    context->postTask(createCallbackTask(&openFileSystem, m_basePath, context->securityOrigin()->databaseIdentifier(), type, new FileSystemCallbacks(successCallback, errorCallback, context)));
+    context->postTask(createCallbackTask(&openFileSystem, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, new FileSystemCallbacks(successCallback, errorCallback, context)));
 }
 
 } // namespace
diff --git a/WebCore/fileapi/LocalFileSystem.h b/WebCore/fileapi/LocalFileSystem.h
index 48cfa8f..d08d0f0 100644
--- a/WebCore/fileapi/LocalFileSystem.h
+++ b/WebCore/fileapi/LocalFileSystem.h
@@ -44,20 +44,44 @@ class ErrorCallback;
 class FileSystemCallback;
 class ScriptExecutionContext;
 
-class LocalFileSystem : public RefCounted<LocalFileSystem> {
+// Keeps per-process information and provides an entry point to open a file system.
+class LocalFileSystem : public Noncopyable {
 public:
-    static PassRefPtr<LocalFileSystem> create(const String& basePath);
-    virtual ~LocalFileSystem() { }
+    // Returns a per-process instance of LocalFileSystem.
+    // Note that LocalFileSystem::initializeLocalFileSystem must be called before
+    // calling this one.
+    static LocalFileSystem& localFileSystem();
 
     void requestFileSystem(ScriptExecutionContext*, AsyncFileSystem::Type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
 
-protected:
+#if !PLATFORM(CHROMIUM)
+    // This call is not thread-safe; must be called before any worker threads are created.
+    void initializeLocalFileSystem(const String&);
+
+    String fileSystemBasePath() const;
+#endif
+
+private:
     LocalFileSystem(const String& basePath)
         : m_basePath(basePath)
     {
     }
 
-    String m_basePath;
+    static LocalFileSystem* s_instance;
+
+    // An inner class that enforces thread-safe string access.
+    class SystemBasePath {
+    public:
+        explicit SystemBasePath(const String& path) : m_value(path) { }
+        operator String() const
+        {
+            return m_value.threadsafeCopy();
+        }
+    private:
+        String m_value;
+    };
+
+    SystemBasePath m_basePath;
 };
 
 } // namespace
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index f5ba25c..6a203cc 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -727,25 +727,16 @@ void DOMWindow::requestFileSystem(int type, long long size, PassRefPtr<FileSyste
     if (!document)
         return;
 
-    if (!m_localFileSystem) {
-        // FIXME: See if access is allowed.
-
-        Page* page = document->page();
-        if (!page) {
-            DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(INVALID_STATE_ERR));
-            return;
-        }
-
-        // FIXME: Get the quota settings as well.
-        String path = page->settings()->fileSystemRootPath();
-        m_localFileSystem = LocalFileSystem::create(path);
+    if (!AsyncFileSystem::isAvailable() || !document->securityOrigin()->canAccessFileSystem()) {
+        DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(SECURITY_ERR));
+        return;
     }
 
-    m_localFileSystem->requestFileSystem(document, static_cast<AsyncFileSystem::Type>(type), size, successCallback, errorCallback);
+    LocalFileSystem::localFileSystem().requestFileSystem(document, static_cast<AsyncFileSystem::Type>(type), size, successCallback, errorCallback);
 }
 
-COMPILE_ASSERT(int(DOMWindow::TEMPORARY) == int(AsyncFileSystem::Temporary), enum_mismatch);
-COMPILE_ASSERT(int(DOMWindow::PERSISTENT) == int(AsyncFileSystem::Persistent), enum_mismatch);
+COMPILE_ASSERT(static_cast<int>(DOMWindow::TEMPORARY) == static_cast<int>(AsyncFileSystem::Temporary), enum_mismatch);
+COMPILE_ASSERT(static_cast<int>(DOMWindow::PERSISTENT) == static_cast<int>(AsyncFileSystem::Persistent), enum_mismatch);
 
 #endif
 
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 1470628..6fd3775 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -58,7 +58,6 @@ namespace WebCore {
     class History;
     class IDBFactory;
     class InspectorTimelineAgent;
-    class LocalFileSystem;
     class Location;
     class StyleMedia;
     class Navigator;
@@ -444,9 +443,6 @@ namespace WebCore {
 #if ENABLE(INDEXED_DATABASE)
         mutable RefPtr<IDBFactory> m_idbFactory;
 #endif
-#if ENABLE(FILE_SYSTEM)
-        RefPtr<LocalFileSystem> m_localFileSystem;
-#endif
 
         EventTargetData m_eventTargetData;
 
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index 4789d3c..2a63966 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -121,6 +121,7 @@ public:
     bool canAccessLocalStorage() const { return !isUnique(); }
     bool canAccessCookies() const { return !isUnique(); }
     bool canAccessPasswordManager() const { return !isUnique(); }
+    bool canAccessFileSystem() const { return !isUnique(); }
 
     // Technically, we should always allow access to sessionStorage, but we
     // currently don't handle creating a sessionStorage area for unique
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 38fbe21..3c95b59 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -498,11 +498,6 @@ void Settings::setLocalStorageDatabasePath(const String& path)
     m_localStorageDatabasePath = path;
 }
 
-void Settings::setFileSystemRootPath(const String& path)
-{
-    m_fileSystemRootPath = path;
-}
-
 void Settings::setApplicationChromeMode(bool mode)
 {
     m_inApplicationChromeMode = mode;
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index a6b7de7..c217a0d 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -241,9 +241,6 @@ namespace WebCore {
         void setLocalStorageDatabasePath(const String&);
         const String& localStorageDatabasePath() const { return m_localStorageDatabasePath; }
 
-        void setFileSystemRootPath(const String&);
-        const String& fileSystemRootPath() const { return m_fileSystemRootPath; }
-
         void setApplicationChromeMode(bool);
         bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
 
@@ -339,7 +336,6 @@ namespace WebCore {
         String m_defaultTextEncodingName;
         String m_ftpDirectoryTemplatePath;
         String m_localStorageDatabasePath;
-        String m_fileSystemRootPath;
         KURL m_userStyleSheetLocation;
         AtomicString m_standardFontFamily;
         AtomicString m_fixedFontFamily;
diff --git a/WebCore/platform/AsyncFileSystem.cpp b/WebCore/platform/AsyncFileSystem.cpp
index b4fcd0d..57305ff 100644
--- a/WebCore/platform/AsyncFileSystem.cpp
+++ b/WebCore/platform/AsyncFileSystem.cpp
@@ -35,12 +35,20 @@
 
 #include "AsyncFileSystemCallbacks.h"
 #include "FileSystem.h"
+#include "NotImplemented.h"
 
 namespace WebCore {
 
+#if !PLATFORM(CHROMIUM)
+bool AsyncFileSystem::isAvailable()
+{
+    notImplemented();
+    return false;
+}
+
 PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create(const String&)
 {
-    // FIXME: return default AsyncFileSystem implementation.
+    notImplemented();
     return 0;
 }
 
@@ -62,6 +70,7 @@ void AsyncFileSystem::openFileSystem(const String& basePath, const String& stora
 
     callbacks->didOpenFileSystem(name, AsyncFileSystem::create(rootPath));
 }
+#endif
 
 // Default implementation.
 String AsyncFileSystem::virtualToPlatformPath(const String& path) const
diff --git a/WebCore/platform/AsyncFileSystem.h b/WebCore/platform/AsyncFileSystem.h
index 71a0cc3..1bf7580 100644
--- a/WebCore/platform/AsyncFileSystem.h
+++ b/WebCore/platform/AsyncFileSystem.h
@@ -57,6 +57,8 @@ public:
     virtual void stop() { }
     virtual bool hasPendingActivity() { return false; }
 
+    static bool isAvailable();
+
     // Creates and returns a new platform-specific AsyncFileSystem instance if the platform has its own implementation.
     static PassOwnPtr<AsyncFileSystem> create(const String& rootPath);
 
diff --git a/WebCore/workers/WorkerContext.cpp b/WebCore/workers/WorkerContext.cpp
index b52b285..4964d05 100644
--- a/WebCore/workers/WorkerContext.cpp
+++ b/WebCore/workers/WorkerContext.cpp
@@ -63,6 +63,15 @@
 #include "NotificationCenter.h"
 #endif
 
+#if ENABLE(FILE_SYSTEM)
+#include "AsyncFileSystem.h"
+#include "DOMFileSystem.h"
+#include "ErrorCallback.h"
+#include "FileError.h"
+#include "FileSystemCallback.h"
+#include "LocalFileSystem.h"
+#endif
+
 namespace WebCore {
 
 class CloseWorkerContextTask : public ScriptExecutionContext::Task {
@@ -100,6 +109,10 @@ WorkerContext::~WorkerContext()
 #if ENABLE(NOTIFICATIONS)
     m_notifications.clear();
 #endif
+
+    // Make sure we have no observers.
+    notifyObserversOfStop();
+
     // Notify proxy that we are going away. This can free the WorkerThread object, so do not access it after this.
     thread()->workerReportingProxy().workerContextDestroyed();
 }
@@ -335,6 +348,68 @@ void WorkerContext::revokeBlobURL(const String& blobURLString)
 }
 #endif
 
+#if ENABLE(FILE_SYSTEM)
+void WorkerContext::requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    if (!AsyncFileSystem::isAvailable() || !securityOrigin()->canAccessFileSystem()) {
+        DOMFileSystem::scheduleCallback(this, errorCallback, FileError::create(SECURITY_ERR));
+        return;
+    }
+
+    LocalFileSystem::localFileSystem().requestFileSystem(this, static_cast<AsyncFileSystem::Type>(type), size, successCallback, errorCallback);
+}
+
+COMPILE_ASSERT(static_cast<int>(WorkerContext::TEMPORARY) == static_cast<int>(AsyncFileSystem::Temporary), enum_mismatch);
+COMPILE_ASSERT(static_cast<int>(WorkerContext::PERSISTENT) == static_cast<int>(AsyncFileSystem::Persistent), enum_mismatch);
+#endif
+
+WorkerContext::Observer::Observer(WorkerContext* context)
+    : m_context(context)
+{
+    ASSERT(m_context && m_context->isContextThread());
+    m_context->registerObserver(this);
+}
+
+WorkerContext::Observer::~Observer()
+{
+    if (!m_context)
+        return;
+    ASSERT(m_context->isContextThread());
+    m_context->unregisterObserver(this);
+}
+
+void WorkerContext::Observer::stopObserving()
+{
+    if (!m_context)
+        return;
+    ASSERT(m_context->isContextThread());
+    m_context->unregisterObserver(this);
+    m_context = 0;
+}
+
+void WorkerContext::registerObserver(Observer* observer)
+{
+    ASSERT(observer);
+    m_workerObservers.add(observer);
+}
+
+void WorkerContext::unregisterObserver(Observer* observer)
+{
+    ASSERT(observer);
+    m_workerObservers.remove(observer);
+}
+
+void WorkerContext::notifyObserversOfStop()
+{
+    HashSet<Observer*>::iterator iter = m_workerObservers.begin();
+    while (iter != m_workerObservers.end()) {
+        WorkerContext::Observer* observer = *iter;
+        observer->stopObserving();
+        observer->notifyStop();
+        iter = m_workerObservers.begin();
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WORKERS)
diff --git a/WebCore/workers/WorkerContext.h b/WebCore/workers/WorkerContext.h
index 7fb8b46..4128a56 100644
--- a/WebCore/workers/WorkerContext.h
+++ b/WebCore/workers/WorkerContext.h
@@ -35,6 +35,7 @@
 #include "ScriptExecutionContext.h"
 #include "WorkerScriptController.h"
 #include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -47,6 +48,8 @@ namespace WebCore {
     class Database;
     class DatabaseCallback;
     class DatabaseSync;
+    class ErrorCallback;
+    class FileSystemCallback;
     class NotificationCenter;
     class ScheduledAction;
     class WorkerLocation;
@@ -121,6 +124,14 @@ namespace WebCore {
         void revokeBlobURL(const String&);
 #endif
 
+#if ENABLE(FILE_SYSTEM)
+        enum FileSystemType {
+            TEMPORARY,
+            PERSISTENT,
+        };
+        void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
+#endif
+
         // These methods are used for GC marking. See JSWorkerContext::markChildren(MarkStack&) in
         // JSWorkerContextCustom.cpp.
         WorkerNavigator* optionalNavigator() const { return m_navigator.get(); }
@@ -131,6 +142,21 @@ namespace WebCore {
 
         bool isClosing() { return m_closing; }
 
+        // An observer interface to be notified when the worker thread is getting stopped.
+        class Observer : public Noncopyable {
+        public:
+            Observer(WorkerContext*);
+            virtual ~Observer();
+            virtual void notifyStop() = 0;
+            void stopObserving();
+        private:
+            WorkerContext* m_context;
+        };
+        friend class Observer;
+        void registerObserver(Observer*);
+        void unregisterObserver(Observer*);
+        void notifyObserversOfStop();
+
     protected:
         WorkerContext(const KURL&, const String&, WorkerThread*);
 
@@ -161,6 +187,8 @@ namespace WebCore {
         bool m_closing;
         bool m_reportingException;
         EventTargetData m_eventTargetData;
+
+        HashSet<Observer*> m_workerObservers;
     };
 
 } // namespace WebCore
diff --git a/WebCore/workers/WorkerContext.idl b/WebCore/workers/WorkerContext.idl
index 02aa4ad..3e185c0 100644
--- a/WebCore/workers/WorkerContext.idl
+++ b/WebCore/workers/WorkerContext.idl
@@ -104,6 +104,14 @@ module threads {
         DOMString createBlobURL(in Blob blob);
         void revokeBlobURL(in DOMString blobURL);
 #endif
+
+#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM
+        const unsigned short TEMPORARY = 0;
+        const unsigned short PERSISTENT = 1;
+        [EnabledAtRuntime] void requestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
+
+                 attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags;
+#endif
     };
 
 }
diff --git a/WebCore/workers/WorkerThread.cpp b/WebCore/workers/WorkerThread.cpp
index d6a1e05..f61120e 100644
--- a/WebCore/workers/WorkerThread.cpp
+++ b/WebCore/workers/WorkerThread.cpp
@@ -202,6 +202,8 @@ public:
 
         workerContext->stopActiveDOMObjects();
 
+        workerContext->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.
         workerContext->removeAllEventListeners();
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 42dae3c..3bf713e 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,35 @@
+2010-09-23  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Add Worker support for FileSystem API
+        https://bugs.webkit.org/show_bug.cgi?id=45808
+
+        Added WebWorkerBase::openFileSystem and WebCommonWorkerClient::
+        openFileSystem to call in to the browser via Worker stub/proxy
+        in the chromium.
+
+        Also added WorkerFileSystemCallbacksBridge class that proxies
+        requests and callbacks between from/to worker thread to/from the
+        main thread.
+
+        * public/WebCommonWorkerClient.h:
+        (WebKit::WebCommonWorkerClient::openFileSystem): Added.
+        * src/LocalFileSystemChromium.cpp:
+        (WebCore::LocalFileSystem::localFileSystem): Added.
+        (WebCore::LocalFileSystem::requestFileSystem): Added implementation
+        for workers. In worker case this calls WebWorkerBase::openFileSystem.
+        * src/WebWorkerBase.cpp:
+        (WebKit::WebWorkerBase::openFileSystem): Added. This is called from
+        LocalFileSystem::requestFileSystem on the worker thread and creates
+        a bridge to call WebCommonWorkerClient::openFileSystem on the main
+        thread.
+        * src/WebWorkerBase.h:
+        * src/WebWorkerClientImpl.h:
+        (WebKit::WebWorkerClientImpl::openFileSystem): Added.
+        * src/WorkerFileSystemCallbacksBridge.cpp: Added.
+        * src/WorkerFileSystemCallbacksBridge.h: Added.
+
 2010-09-23  Tony Chang  <tony at chromium.org>
 
         Reviewed by Dimitri Glazkov.
diff --git a/WebKit/chromium/WebKit.gyp b/WebKit/chromium/WebKit.gyp
index a5c9c0d..48f9db8 100644
--- a/WebKit/chromium/WebKit.gyp
+++ b/WebKit/chromium/WebKit.gyp
@@ -532,6 +532,8 @@
                 'src/WebWorkerClientImpl.h',
                 'src/WebWorkerImpl.cpp',
                 'src/WebWorkerImpl.h',
+                'src/WorkerFileSystemCallbacksBridge.cpp',
+                'src/WorkerFileSystemCallbacksBridge.h',
                 'src/WrappedResourceRequest.h',
                 'src/WrappedResourceResponse.h',
                 'src/win/WebInputEventFactory.cpp',
diff --git a/WebKit/chromium/public/WebCommonWorkerClient.h b/WebKit/chromium/public/WebCommonWorkerClient.h
index cea6471..39d8aa9 100644
--- a/WebKit/chromium/public/WebCommonWorkerClient.h
+++ b/WebKit/chromium/public/WebCommonWorkerClient.h
@@ -31,6 +31,9 @@
 #ifndef WebCommonWorkerClient_h
 #define WebCommonWorkerClient_h
 
+#include "WebCommon.h"
+#include "WebFileSystem.h"
+
 namespace WebKit {
 
 class WebApplicationCacheHost;
@@ -83,6 +86,12 @@ public:
     // Called on the main webkit thread before opening a web database.
     virtual bool allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize) = 0;
 
+    // Called on the main webkit thread before opening a file system.
+    virtual void openFileSystem(WebFileSystem::Type, long long size, WebFileSystemCallbacks*)
+    {
+        WEBKIT_ASSERT_NOT_REACHED();
+    }
+
 protected:
     ~WebCommonWorkerClient() { }
 };
diff --git a/WebKit/chromium/src/AsyncFileSystemChromium.cpp b/WebKit/chromium/src/AsyncFileSystemChromium.cpp
index 430b2fb..db65bbd 100644
--- a/WebKit/chromium/src/AsyncFileSystemChromium.cpp
+++ b/WebKit/chromium/src/AsyncFileSystemChromium.cpp
@@ -45,6 +45,11 @@
 
 namespace WebCore {
 
+bool AsyncFileSystem::isAvailable()
+{
+    return true;
+}
+
 AsyncFileSystemChromium::AsyncFileSystemChromium(const String& rootPath)
     : AsyncFileSystem(rootPath)
     , m_webFileSystem(WebKit::webKitClient()->fileSystem())
diff --git a/WebKit/chromium/src/LocalFileSystemChromium.cpp b/WebKit/chromium/src/LocalFileSystemChromium.cpp
index 45365ef..994f310 100644
--- a/WebKit/chromium/src/LocalFileSystemChromium.cpp
+++ b/WebKit/chromium/src/LocalFileSystemChromium.cpp
@@ -42,14 +42,19 @@
 #include "WebFileSystemCallbacksImpl.h"
 #include "WebFrameClient.h"
 #include "WebFrameImpl.h"
+#include "WebWorkerImpl.h"
+#include "WorkerContext.h"
+#include "WorkerThread.h"
+#include <wtf/Threading.h>
 
 using namespace WebKit;
 
 namespace WebCore {
 
-PassRefPtr<LocalFileSystem> LocalFileSystem::create(const String& path)
+LocalFileSystem& LocalFileSystem::localFileSystem()
 {
-    return adoptRef(new LocalFileSystem(path));
+    AtomicallyInitializedStatic(LocalFileSystem*, localFileSystem = new LocalFileSystem(""));
+    return *localFileSystem;
 }
 
 void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
@@ -60,7 +65,10 @@ void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFi
         WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
         webFrame->client()->openFileSystem(webFrame, static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(new FileSystemCallbacks(successCallback, errorCallback, context)));
     } else {
-        // FIXME: Add implementation for workers.
+        WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+        WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy();
+        WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerLoaderProxy);
+        webWorker->openFileSystem(static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(new FileSystemCallbacks(successCallback, errorCallback, context)));
     }
 }
 
diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp
index 42f41d2..a69aada 100644
--- a/WebKit/chromium/src/WebWorkerBase.cpp
+++ b/WebKit/chromium/src/WebWorkerBase.cpp
@@ -37,6 +37,7 @@
 #include "PlatformMessagePortChannel.h"
 
 #include "WebDataSourceImpl.h"
+#include "WebFileError.h"
 #include "WebFrameClient.h"
 #include "WebFrameImpl.h"
 #include "WebMessagePortChannel.h"
@@ -45,6 +46,8 @@
 #include "WebView.h"
 #include "WebWorkerClient.h"
 
+#include "WorkerContext.h"
+#include "WorkerFileSystemCallbacksBridge.h"
 #include "WorkerScriptController.h"
 #include "WorkerThread.h"
 #include <wtf/MainThread.h>
@@ -56,6 +59,7 @@ namespace WebKit {
 #if ENABLE(WORKERS)
 
 static const char allowDatabaseMode[] = "allowDatabaseMode";
+static const char openFileSystemMode[] = "openFileSystemMode";
 
 namespace {
 
@@ -114,6 +118,7 @@ private:
     WebWorkerBase* m_worker;
     WTF::String m_mode;
 };
+
 }
 
 // This function is called on the main thread to force to initialize some static
@@ -231,6 +236,16 @@ bool WebWorkerBase::allowDatabase(WebFrame*, const WebString& name, const WebStr
     return bridge->result();
 }
 
+void WebWorkerBase::openFileSystem(WebFileSystem::Type type, long long size, WebFileSystemCallbacks* callbacks)
+{
+    WorkerRunLoop& runLoop = m_workerThread->runLoop();
+    WorkerScriptController* controller = WorkerScriptController::controllerForContext();
+    WorkerContext* workerContext = controller->workerContext();
+
+    RefPtr<WorkerFileSystemCallbacksBridge> bridge = WorkerFileSystemCallbacksBridge::create(this, workerContext, callbacks);
+    bridge->postOpenFileSystemToMainThread(commonClient(), type, size, openFileSystemMode);
+}
+
 // WorkerObjectProxy -----------------------------------------------------------
 
 void WebWorkerBase::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message,
diff --git a/WebKit/chromium/src/WebWorkerBase.h b/WebKit/chromium/src/WebWorkerBase.h
index 22711f9..628d8f1 100644
--- a/WebKit/chromium/src/WebWorkerBase.h
+++ b/WebKit/chromium/src/WebWorkerBase.h
@@ -91,6 +91,9 @@ public:
     // Controls whether access to Web Databases is allowed for this worker.
     virtual bool allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize);
 
+    // Requests to open a file system for this worker. (Note that this is not the implementation for WebFrameClient::openFileSystem.)
+    void openFileSystem(WebFileSystem::Type, long long size, WebFileSystemCallbacks*);
+
     // Executes the given task on the main thread.
     static void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
 
diff --git a/WebKit/chromium/src/WebWorkerClientImpl.h b/WebKit/chromium/src/WebWorkerClientImpl.h
index 741d606..0604823 100644
--- a/WebKit/chromium/src/WebWorkerClientImpl.h
+++ b/WebKit/chromium/src/WebWorkerClientImpl.h
@@ -33,8 +33,8 @@
 
 #if ENABLE(WORKERS)
 
+#include "WebFileSystem.h"
 #include "WebWorkerClient.h"
-
 #include "WorkerContextProxy.h"
 #include <wtf/PassOwnPtr.h>
 #include <wtf/RefPtr.h>
@@ -99,6 +99,10 @@ public:
         ASSERT_NOT_REACHED();
         return true;
     }
+    virtual void openFileSystem(WebFrame*, WebFileSystem::Type, long long size, WebFileSystemCallbacks*)
+    {
+        ASSERT_NOT_REACHED();
+    }
 
 private:
     virtual ~WebWorkerClientImpl();
diff --git a/WebKit/chromium/src/WorkerFileSystemCallbacksBridge.cpp b/WebKit/chromium/src/WorkerFileSystemCallbacksBridge.cpp
new file mode 100644
index 0000000..d112886
--- /dev/null
+++ b/WebKit/chromium/src/WorkerFileSystemCallbacksBridge.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2010 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"
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "CrossThreadTask.h"
+#include "WebCommonWorkerClient.h"
+#include "WebFileSystemCallbacks.h"
+#include "WebString.h"
+#include "WebWorkerBase.h"
+#include "WorkerContext.h"
+#include "WorkerScriptController.h"
+#include "WorkerThread.h"
+#include <wtf/MainThread.h>
+#include <wtf/Threading.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// FileSystemCallbacks that are to be dispatched on the main thread.
+class MainThreadFileSystemCallbacks : public WebFileSystemCallbacks {
+public:
+    static PassOwnPtr<MainThreadFileSystemCallbacks> create(PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode)
+    {
+        return adoptPtr(new MainThreadFileSystemCallbacks(bridge, mode));
+    }
+
+    virtual ~MainThreadFileSystemCallbacks()
+    {
+    }
+
+    virtual void didOpenFileSystem(const WebString& name, const WebString& path)
+    {
+        m_bridge->didOpenFileSystemOnMainThread(name, path, m_mode);
+        delete this;
+    }
+
+    virtual void didFail(WebFileError error)
+    {
+        m_bridge->didFailOnMainThread(error, m_mode);
+        delete this;
+    }
+
+    virtual void didSucceed()
+    {
+        WEBKIT_ASSERT_NOT_REACHED();
+    }
+
+    virtual void didReadMetadata(const WebFileInfo& info)
+    {
+        WEBKIT_ASSERT_NOT_REACHED();
+    }
+
+    virtual void didReadDirectory(const WebVector<WebFileSystemEntry>& entries, bool hasMore)
+    {
+        WEBKIT_ASSERT_NOT_REACHED();
+    }
+
+private:
+    MainThreadFileSystemCallbacks(PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& mode)
+        : m_bridge(bridge)
+        , m_mode(mode)
+    {
+        ASSERT(m_bridge.get());
+    }
+
+    friend class WorkerFileSystemCallbacksBridge;
+    RefPtr<WorkerFileSystemCallbacksBridge> m_bridge;
+    const String m_mode;
+};
+
+void WorkerFileSystemCallbacksBridge::stop()
+{
+    ASSERT(m_workerContext->isContextThread());
+    MutexLocker locker(m_mutex);
+    m_worker = 0;
+
+    if (m_callbacksOnWorkerThread) {
+        m_callbacksOnWorkerThread->didFail(WebFileErrorAbort);
+        m_callbacksOnWorkerThread = 0;
+    }
+}
+
+void WorkerFileSystemCallbacksBridge::postOpenFileSystemToMainThread(WebCommonWorkerClient* commonClient, WebFileSystem::Type type, long long size, const String& mode)
+{
+    m_selfRef = this;
+    ASSERT(m_workerContext->isContextThread());
+    ASSERT(m_worker);
+    m_worker->dispatchTaskToMainThread(createCallbackTask(&openFileSystemOnMainThread, commonClient, type, size, this, mode));
+}
+
+void WorkerFileSystemCallbacksBridge::openFileSystemOnMainThread(ScriptExecutionContext*, WebCommonWorkerClient* commonClient, WebFileSystem::Type type, long long size, WorkerFileSystemCallbacksBridge* bridge, const String& mode)
+{
+    ASSERT(isMainThread());
+    if (!commonClient)
+        bridge->didFailOnMainThread(WebFileErrorAbort, mode);
+    else {
+        // MainThreadFileSystemCallbacks is self-destructed, so we leak ptr here.
+        commonClient->openFileSystem(type, size, MainThreadFileSystemCallbacks::create(bridge, mode).leakPtr());
+    }
+}
+
+void WorkerFileSystemCallbacksBridge::didFailOnMainThread(WebFileError error, const String& mode)
+{
+    ASSERT(isMainThread());
+    mayPostTaskToWorker(createCallbackTask(&didFailOnWorkerThread, m_selfRef, error), mode);
+}
+
+void WorkerFileSystemCallbacksBridge::didOpenFileSystemOnMainThread(const String& name, const String& rootPath, const String& mode)
+{
+    ASSERT(isMainThread());
+    mayPostTaskToWorker(createCallbackTask(&didOpenFileSystemOnWorkerThread, m_selfRef, name, rootPath), mode);
+}
+
+WorkerFileSystemCallbacksBridge::WorkerFileSystemCallbacksBridge(WebWorkerBase* worker, ScriptExecutionContext* scriptExecutionContext, WebFileSystemCallbacks* callbacks)
+    : WorkerContext::Observer(static_cast<WorkerContext*>(scriptExecutionContext))
+    , m_worker(worker)
+    , m_workerContext(scriptExecutionContext)
+    , m_callbacksOnWorkerThread(callbacks)
+{
+    ASSERT(m_workerContext->isContextThread());
+}
+
+WorkerFileSystemCallbacksBridge::~WorkerFileSystemCallbacksBridge()
+{
+    ASSERT(!m_callbacksOnWorkerThread);
+}
+
+void WorkerFileSystemCallbacksBridge::didFailOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, WebFileError error)
+{
+    if (bridge->m_callbacksOnWorkerThread) {
+        ASSERT(bridge->m_workerContext->isContextThread());
+        bridge->m_callbacksOnWorkerThread->didFail(error);
+        bridge->m_callbacksOnWorkerThread = 0;
+    }
+}
+
+void WorkerFileSystemCallbacksBridge::didOpenFileSystemOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge> bridge, const String& name, const String& rootPath)
+{
+    if (bridge->m_callbacksOnWorkerThread) {
+        ASSERT(bridge->m_workerContext->isContextThread());
+        bridge->m_callbacksOnWorkerThread->didOpenFileSystem(name, rootPath);
+        bridge->m_callbacksOnWorkerThread = 0;
+    }
+}
+
+void WorkerFileSystemCallbacksBridge::mayPostTaskToWorker(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+    { // Let go of the mutex before possibly deleting this due to m_selfRef.clear().
+        MutexLocker locker(m_mutex);
+        if (m_worker)
+            m_worker->postTaskForModeToWorkerContext(task, mode);
+    }
+    m_selfRef.clear();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILE_SYSTEM)
diff --git a/WebKit/chromium/src/WorkerFileSystemCallbacksBridge.h b/WebKit/chromium/src/WorkerFileSystemCallbacksBridge.h
new file mode 100644
index 0000000..cbfc690
--- /dev/null
+++ b/WebKit/chromium/src/WorkerFileSystemCallbacksBridge.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef WorkerFileSystemCallbacksBridge_h
+#define WorkerFileSystemCallbacksBridge_h
+
+#include "PlatformString.h"
+#include "ScriptExecutionContext.h"
+#include "WebFileError.h"
+#include "WebFileSystem.h"
+#include "WebVector.h"
+#include "WorkerContext.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebKit {
+
+class AsyncFileSystem;
+class MainThreadFileSystemCallbacks;
+class ThreadableCallbacksBridgeWrapper;
+class WebCommonWorkerClient;
+class WebFileSystemCallbacks;
+class WebFileSystemEntry;
+class WebWorkerBase;
+struct WebFileInfo;
+
+// This class is used to post a openFileSystem request to the main thread and get called back for the request. This must be destructed on the worker thread.
+//
+// A typical flow for openFileSystem would look like this:
+// Bridge::postOpenFileSystemToMainThread() on WorkerThread
+//  --> Bridge::openFileSystemOnMainThread() is called on MainThread
+//      This makes an IPC with a MainThreadFileSystemCallbacks instance
+//     [actual operation is down in the browser]
+//  --> MainThreadFileSystemCallbacks::didXxx is called on MainThread
+//  --> Bridge::didXxxOnMainThread is called on MainThread
+//  --> Bridge::didXxxOnWorkerThread is called on WorkerThread
+//      This calls the original callbacks (m_callbacksOnWorkerThread) and
+//      releases a self-reference to the bridge.
+class WorkerFileSystemCallbacksBridge : public ThreadSafeShared<WorkerFileSystemCallbacksBridge>, public WebCore::WorkerContext::Observer {
+public:
+    static PassRefPtr<WorkerFileSystemCallbacksBridge> create(WebWorkerBase* worker, WebCore::ScriptExecutionContext* workerContext, WebFileSystemCallbacks* callbacks)
+    {
+        return WTF::adoptRef(new WorkerFileSystemCallbacksBridge(worker, workerContext, callbacks));
+    }
+
+    // WorkerContext::Observer method.
+    virtual void notifyStop()
+    {
+        stop();
+    }
+
+    void stop();
+
+    // Posts an initial request task to the main thread. It is supposed to be called immediately after the bridge is constructed. (It doesn't check if the context has been stopped or not.)
+    void postOpenFileSystemToMainThread(WebCommonWorkerClient*, WebFileSystem::Type, long long size, const String& mode);
+
+    // Callback methods that are called on the main thread.
+    void didFailOnMainThread(WebFileError, const String& mode);
+    void didOpenFileSystemOnMainThread(const String& name, const String& rootPath, const String& mode);
+
+private:
+    WorkerFileSystemCallbacksBridge(WebWorkerBase*, WebCore::ScriptExecutionContext*, WebFileSystemCallbacks*);
+    ~WorkerFileSystemCallbacksBridge();
+
+    friend class ThreadSafeShared<WorkerFileSystemCallbacksBridge>;
+
+    // Method that is to be called on the main thread.
+    static void openFileSystemOnMainThread(WebCore::ScriptExecutionContext*, WebCommonWorkerClient*, WebFileSystem::Type, long long size, WorkerFileSystemCallbacksBridge*, const String& mode);
+
+    friend class MainThreadFileSystemCallbacks;
+
+    // Methods that dispatch WebFileSystemCallbacks on the worker threads.
+    // They release a selfRef of the WorkerFileSystemCallbacksBridge.
+    static void didFailOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge>, WebFileError);
+    static void didOpenFileSystemOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge>, const String& name, const String& rootPath);
+
+    void mayPostTaskToWorker(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode);
+
+    // m_selfRef keeps a reference to itself until a task is created for the worker thread (at which point the task holds the reference).
+    RefPtr<WorkerFileSystemCallbacksBridge> m_selfRef;
+
+    Mutex m_mutex;
+    WebWorkerBase* m_worker;
+    WebCore::ScriptExecutionContext* m_workerContext;
+
+    // This is self-destructed and must be fired on the worker thread.
+    WebFileSystemCallbacks* m_callbacksOnWorkerThread;
+};
+
+} // namespace WebCore
+
+#endif // WorkerFileSystemCallbacksBridge_h

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list