16b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner/* 26b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * Copyright (C) 2010 Google Inc. All rights reserved. 36b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 46b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * Redistribution and use in source and binary forms, with or without 56b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * modification, are permitted provided that the following conditions are 66b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * met: 76b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 86b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * * Redistributions of source code must retain the above copyright 96b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * notice, this list of conditions and the following disclaimer. 106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * * Redistributions in binary form must reproduce the above 116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * copyright notice, this list of conditions and the following disclaimer 126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * in the documentation and/or other materials provided with the 136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * distribution. 146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * * Neither the name of Google Inc. nor the names of its 156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * contributors may be used to endorse or promote products derived from 166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * this software without specific prior written permission. 176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner */ 306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#ifndef WorkerFileWriterCallbacksBridge_h 326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#define WorkerFileWriterCallbacksBridge_h 336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if ENABLE(FILE_SYSTEM) 356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "WebFileError.h" 376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "WebFileWriterClient.h" 386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "WorkerContext.h" 396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include <wtf/PassOwnPtr.h> 406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include <wtf/PassRefPtr.h> 412bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/ThreadSafeRefCounted.h> 426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennernamespace WebCore { 446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner class AsyncFileWriterClient; 456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner class KURL; 466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner class WorkerLoaderProxy; 476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennernamespace WTF { 506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner class String; 516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerusing WTF::String; 536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennernamespace WebKit { 556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerclass WebFileSystem; 576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerclass WebFileWriter; 586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerclass WebFileWriterClient; 596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerclass WebWorkerBase; 606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// This class is used as a mechanism to bridge calls between threads. 626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// Calls to a WebFileWriter must happen on the main thread, but they come from 636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// the context thread. The responses through the WebFileWriterClient interface 646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// start on the main thread, but must be sent via the worker context thread. 656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// 666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// A typical flow for write would look like this: 676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// Bridge::postWriteToMainThread() on WorkerThread 686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// --> Bridge::writeOnMainThread() is called on MainThread 696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// --> WebFileWriter::write() 706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// This makes an IPC; the actual operation is down in the browser. 716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// --> Bridge::didWrite is called on MainThread 726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// --> Bridge::didWriteOnWorkerThread is called on WorkerThread 736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// This calls the original client (m_clientOnWorkerThread). 746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// 756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// The bridge object is refcounted, so that it doesn't get deleted while there 766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// are cross-thread calls in flight. Each CrossThreadTask carries a reference 776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// to the bridge, which guarantees that the bridge will still be valid when the 786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// task is executed. In order to shut down the bridge, the WebFileWriterClient 796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// should call postShutdownToMainThread before dropping its reference to the 806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// bridge. This ensures that the WebFileWriter will be cleared on the main 816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// thread and that no further calls to the WebFileWriterClient will be made. 822bde8e466a4451c7319e3a072d118917957d6554Steve Blockclass WorkerFileWriterCallbacksBridge : public ThreadSafeRefCounted<WorkerFileWriterCallbacksBridge>, public WebCore::WorkerContext::Observer, public WebFileWriterClient { 836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerpublic: 846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ~WorkerFileWriterCallbacksBridge(); 856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // WorkerContext::Observer method. 876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner virtual void notifyStop(); 886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static PassRefPtr<WorkerFileWriterCallbacksBridge> create(const String& path, WebCore::WorkerLoaderProxy* proxy, WebCore::ScriptExecutionContext* workerContext, WebCore::AsyncFileWriterClient* client) 906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner { 916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return adoptRef(new WorkerFileWriterCallbacksBridge(path, proxy, workerContext, client)); 926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Methods that create an instance and post an initial request task to the main thread. They must be called on the worker thread. 956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void postWriteToMainThread(long long position, const WebCore::KURL& data); 966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void postTruncateToMainThread(long long length); 976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void postAbortToMainThread(); 986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // The owning WorkerAsyncFileWriterChromium should call this method before dropping its last reference to the bridge, on the context thread. 1006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // The actual deletion of the WorkerFileWriterCallbacksBridge may happen on either the main or context thread, depending on where the last reference goes away; that's safe as long as this is called first. 1016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void postShutdownToMainThread(PassRefPtr<WorkerFileWriterCallbacksBridge>); 1026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Callback methods that are called on the main thread. 1046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // These are the implementation of WebKit::WebFileWriterClient. 1056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void didWrite(long long bytes, bool complete); 1066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void didFail(WebFileError); 1076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void didTruncate(); 1086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Call this on the context thread to wait for the current operation to complete. 1104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bool waitForOperationToComplete(); 1114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 1126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerprivate: 1136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner WorkerFileWriterCallbacksBridge(const String& path, WebCore::WorkerLoaderProxy*, WebCore::ScriptExecutionContext*, WebCore::AsyncFileWriterClient*); 1146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void postInitToMainThread(const String& path); 1166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Methods that are to be called on the main thread. 1186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void writeOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, long long position, const WebCore::KURL& data); 1196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void truncateOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, long long length); 1206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void abortOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>); 1216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void initOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, const String& path); 1226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void shutdownOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>); 1236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Methods that dispatch to AsyncFileWriterClient on the worker threads. 1256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void didWriteOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, long long length, bool complete); 1266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void didFailOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, WebFileError); 1276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void didTruncateOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>); 1286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Called on the main thread to run the supplied task. 1306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void runTaskOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 1316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Called on the worker thread to run the supplied task. 1326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner static void runTaskOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 1336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Called on the worker thread to dispatch to the main thread. 1356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 1366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Called on the main thread to dispatch to the worker thread. 1376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner void dispatchTaskToWorkerThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); 1386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Used from the main thread to post tasks to the context thread. 1406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner WebCore::WorkerLoaderProxy* m_proxy; 1416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Used on the context thread, only to check that we're running on the context thread. 1436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner WebCore::ScriptExecutionContext* m_workerContext; 1446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Created and destroyed from the main thread. 1466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner OwnPtr<WebKit::WebFileWriter> m_writer; 1476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Used on the context thread to call back into the client. 1496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner WebCore::AsyncFileWriterClient* m_clientOnWorkerThread; 1506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Used to indicate that shutdown has started on the main thread, and hence the writer has been deleted. 1526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner bool m_writerDeleted; 1534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 1544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Used by waitForOperationToComplete. 1554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bool m_operationInProgress; 1564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 1574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Used by postTaskForModeToWorkerContext and runInMode. 1584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang String m_mode; 1596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}; 1606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} // namespace WebCore 1626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif 1646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif // WorkerFileWriterCallbacksBridge_h 166