summaryrefslogtreecommitdiffstats
path: root/WebCore/workers
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/workers')
-rw-r--r--WebCore/workers/WorkerContext.cpp82
-rw-r--r--WebCore/workers/WorkerContext.h28
-rw-r--r--WebCore/workers/WorkerContext.idl8
-rw-r--r--WebCore/workers/WorkerThread.cpp2
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();