1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef WorkerFileSystemCallbacksBridge_h 32 #define WorkerFileSystemCallbacksBridge_h 33 34 #if ENABLE(FILE_SYSTEM) 35 36 #include "PlatformString.h" 37 #include "ScriptExecutionContext.h" 38 #include "WebFileError.h" 39 #include "WebFileSystem.h" 40 #include "WebVector.h" 41 #include "WorkerContext.h" 42 #include <wtf/PassOwnPtr.h> 43 #include <wtf/PassRefPtr.h> 44 #include <wtf/Threading.h> 45 46 namespace WebKit { 47 48 class AsyncFileSystem; 49 class MainThreadFileSystemCallbacks; 50 class ThreadableCallbacksBridgeWrapper; 51 class WebCommonWorkerClient; 52 class WebFileSystemCallbacks; 53 class WebWorkerBase; 54 struct WebFileInfo; 55 struct WebFileSystemEntry; 56 57 // 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. 58 // 59 // A typical flow for openFileSystem would look like this: 60 // Bridge::postOpenFileSystemToMainThread() on WorkerThread 61 // --> Bridge::openFileSystemOnMainThread() is called on MainThread 62 // This makes an IPC with a MainThreadFileSystemCallbacks instance 63 // [actual operation is down in the browser] 64 // --> MainThreadFileSystemCallbacks::didXxx is called on MainThread 65 // --> Bridge::didXxxOnMainThread is called on MainThread 66 // --> Bridge::didXxxOnWorkerThread is called on WorkerThread 67 // This calls the original callbacks (m_callbacksOnWorkerThread) and 68 // releases a self-reference to the bridge. 69 class WorkerFileSystemCallbacksBridge : public ThreadSafeRefCounted<WorkerFileSystemCallbacksBridge>, public WebCore::WorkerContext::Observer { 70 public: 71 ~WorkerFileSystemCallbacksBridge(); 72 73 // WorkerContext::Observer method. 74 virtual void notifyStop() 75 { 76 stop(); 77 } 78 79 void stop(); 80 81 static PassRefPtr<WorkerFileSystemCallbacksBridge> create(WebWorkerBase* worker, WebCore::ScriptExecutionContext* workerContext, WebFileSystemCallbacks* callbacks) 82 { 83 return adoptRef(new WorkerFileSystemCallbacksBridge(worker, workerContext, callbacks)); 84 } 85 86 // Methods that create an instance and post an initial request task to the main thread. They must be called on the worker thread. 87 void postOpenFileSystemToMainThread(WebCommonWorkerClient*, WebFileSystem::Type, long long size, bool create, const String& mode); 88 void postMoveToMainThread(WebFileSystem*, const String& srcPath, const String& destPath, const String& mode); 89 void postCopyToMainThread(WebFileSystem*, const String& srcPath, const String& destPath, const String& mode); 90 void postRemoveToMainThread(WebFileSystem*, const String& path, const String& mode); 91 void postRemoveRecursivelyToMainThread(WebFileSystem*, const String& path, const String& mode); 92 void postReadMetadataToMainThread(WebFileSystem*, const String& path, const String& mode); 93 void postCreateFileToMainThread(WebFileSystem*, const String& path, bool exclusive, const String& mode); 94 void postCreateDirectoryToMainThread(WebFileSystem*, const String& path, bool exclusive, const String& mode); 95 void postFileExistsToMainThread(WebFileSystem*, const String& path, const String& mode); 96 void postDirectoryExistsToMainThread(WebFileSystem*, const String& path, const String& mode); 97 void postReadDirectoryToMainThread(WebFileSystem*, const String& path, const String& mode); 98 99 // Callback methods that are called on the main thread. 100 void didFailOnMainThread(WebFileError, const String& mode); 101 void didOpenFileSystemOnMainThread(const String& name, const String& rootPath, const String& mode); 102 void didSucceedOnMainThread(const String& mode); 103 void didReadMetadataOnMainThread(const WebFileInfo&, const String& mode); 104 void didReadDirectoryOnMainThread(const WebVector<WebFileSystemEntry>&, bool hasMore, const String& mode); 105 106 private: 107 WorkerFileSystemCallbacksBridge(WebWorkerBase*, WebCore::ScriptExecutionContext*, WebFileSystemCallbacks*); 108 109 // Methods that are to be called on the main thread. 110 static void openFileSystemOnMainThread(WebCore::ScriptExecutionContext*, WebCommonWorkerClient*, WebFileSystem::Type, long long size, bool create, WorkerFileSystemCallbacksBridge*, const String& mode); 111 static void moveOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& srcPath, const String& destPath, WorkerFileSystemCallbacksBridge*, const String& mode); 112 static void copyOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& srcPath, const String& destPath, WorkerFileSystemCallbacksBridge*, const String& mode); 113 static void removeOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, WorkerFileSystemCallbacksBridge*, const String& mode); 114 static void removeRecursivelyOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, WorkerFileSystemCallbacksBridge*, const String& mode); 115 static void readMetadataOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, WorkerFileSystemCallbacksBridge*, const String& mode); 116 static void createFileOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, bool exclusive, WorkerFileSystemCallbacksBridge*, const String& mode); 117 static void createDirectoryOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, bool exclusive, WorkerFileSystemCallbacksBridge*, const String& mode); 118 static void fileExistsOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, WorkerFileSystemCallbacksBridge*, const String& mode); 119 static void directoryExistsOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, WorkerFileSystemCallbacksBridge*, const String& mode); 120 static void readDirectoryOnMainThread(WebCore::ScriptExecutionContext*, WebFileSystem*, const String& path, WorkerFileSystemCallbacksBridge*, const String& mode); 121 122 friend class MainThreadFileSystemCallbacks; 123 124 // Methods that dispatch WebFileSystemCallbacks on the worker threads. 125 static void didFailOnWorkerThread(WebCore::ScriptExecutionContext*, WorkerFileSystemCallbacksBridge*, WebFileError); 126 static void didOpenFileSystemOnWorkerThread(WebCore::ScriptExecutionContext*, WorkerFileSystemCallbacksBridge*, const String& name, const String& rootPath); 127 static void didSucceedOnWorkerThread(WebCore::ScriptExecutionContext*, WorkerFileSystemCallbacksBridge*); 128 static void didReadMetadataOnWorkerThread(WebCore::ScriptExecutionContext*, WorkerFileSystemCallbacksBridge*, const WebFileInfo&); 129 static void didReadDirectoryOnWorkerThread(WebCore::ScriptExecutionContext*, WorkerFileSystemCallbacksBridge*, const WebVector<WebFileSystemEntry>&, bool hasMore); 130 131 static void runTaskOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 132 static void runTaskOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileSystemCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 133 134 void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 135 void mayPostTaskToWorker(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode); 136 137 Mutex m_mutex; 138 WebWorkerBase* m_worker; 139 WebCore::ScriptExecutionContext* m_workerContext; 140 141 // This is self-destructed and must be fired on the worker thread. 142 WebFileSystemCallbacks* m_callbacksOnWorkerThread; 143 }; 144 145 } // namespace WebCore 146 147 #endif 148 149 #endif // WorkerFileSystemCallbacksBridge_h 150