diff options
Diffstat (limited to 'WebCore/workers')
-rw-r--r-- | WebCore/workers/WorkerContext.cpp | 82 | ||||
-rw-r--r-- | WebCore/workers/WorkerContext.h | 28 | ||||
-rw-r--r-- | WebCore/workers/WorkerContext.idl | 8 | ||||
-rw-r--r-- | WebCore/workers/WorkerThread.cpp | 2 |
4 files changed, 120 insertions, 0 deletions
diff --git a/WebCore/workers/WorkerContext.cpp b/WebCore/workers/WorkerContext.cpp index b52b285..6cee246 100644 --- a/WebCore/workers/WorkerContext.cpp +++ b/WebCore/workers/WorkerContext.cpp @@ -63,6 +63,16 @@ #include "NotificationCenter.h" #endif +#if ENABLE(FILE_SYSTEM) +#include "AsyncFileSystem.h" +#include "DOMFileSystem.h" +#include "ErrorCallback.h" +#include "FileError.h" +#include "FileSystemCallback.h" +#include "FileSystemCallbacks.h" +#include "LocalFileSystem.h" +#endif + namespace WebCore { class CloseWorkerContextTask : public ScriptExecutionContext::Task { @@ -100,6 +110,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 +349,74 @@ 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; + } + + AsyncFileSystem::Type fileSystemType = static_cast<AsyncFileSystem::Type>(type); + if (fileSystemType != AsyncFileSystem::Temporary && fileSystemType != AsyncFileSystem::Persistent) { + DOMFileSystem::scheduleCallback(this, errorCallback, FileError::create(INVALID_MODIFICATION_ERR)); + return; + } + + LocalFileSystem::localFileSystem().requestFileSystem(this, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, this)); +} + +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(); |