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