[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

jianli at chromium.org jianli at chromium.org
Wed Dec 22 12:14:25 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 5dd8e7e801bd4b2ccfd202625cd898e7b4927356
Author: jianli at chromium.org <jianli at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Aug 17 18:31:40 2010 +0000

    Change FileStream implementation to prepare for blob resource handling.
    https://bugs.webkit.org/show_bug.cgi?id=43985
    
    Reviewed by David Levin.
    
    Change FileStream to support synchronous usage only. All the asychronous
    logics are moved to FileStreamProxy. Update the existing FileReader code
    to adapt to this change.
    
    * html/FileReader.cpp: Account for FileStreamProxy changes.
    (WebCore::FileReader::didStart):
    (WebCore::FileReader::didGetSize):
    (WebCore::FileReader::didOpen):
    (WebCore::FileReader::didRead):
    * html/FileReader.h:
    * html/FileStream.cpp: Remove m_client and make all calls synchronous only.
    (WebCore::FileStream::FileStream):
    (WebCore::FileStream::start):
    (WebCore::FileStream::stop):
    (WebCore::FileStream::getSize):
    (WebCore::FileStream::openForRead):
    (WebCore::FileStream::openForWrite):
    (WebCore::FileStream::close):
    (WebCore::FileStream::read):
    (WebCore::FileStream::write):
    (WebCore::FileStream::truncate):
    * html/FileStream.h: Add getSize() and make all calls synchronous by adding return values.
    (WebCore::FileStream::create):
    * html/FileStreamClient.h: Account for FileStreamProxy changes.
    (WebCore::FileStreamClient::didRead):
    (WebCore::FileStreamClient::didTruncate):
    (WebCore::FileStreamClient::didOpen):
    * html/FileStreamProxy.cpp: All the logics to handle asynchronous calls are wrapped here.
    (WebCore::FileStreamProxy::FileStreamProxy):
    (WebCore::FileStreamProxy::create):
    (WebCore::FileStreamProxy::fileThread):
    (WebCore::didStart):
    (WebCore::FileStreamProxy::startOnFileThread):
    (WebCore::FileStreamProxy::stop):
    (WebCore::derefProxyOnContext):
    (WebCore::FileStreamProxy::stopOnFileThread):
    (WebCore::didGetSize):
    (WebCore::FileStreamProxy::getSize):
    (WebCore::FileStreamProxy::getSizeOnFileThread):
    (WebCore::didOpen):
    (WebCore::FileStreamProxy::openForRead):
    (WebCore::FileStreamProxy::openForReadOnFileThread):
    (WebCore::FileStreamProxy::openForWrite):
    (WebCore::FileStreamProxy::openForWriteOnFileThread):
    (WebCore::FileStreamProxy::close):
    (WebCore::FileStreamProxy::closeOnFileThread):
    (WebCore::didRead):
    (WebCore::FileStreamProxy::read):
    (WebCore::FileStreamProxy::readOnFileThread):
    (WebCore::didWrite):
    (WebCore::FileStreamProxy::write):
    (WebCore::FileStreamProxy::writeOnFileThread):
    (WebCore::didTruncate):
    (WebCore::FileStreamProxy::truncate):
    (WebCore::FileStreamProxy::truncateOnFileThread):
    * html/FileStreamProxy.h:
    * html/FileThreadTask.h: Change all methods to return void since return value is not needed now.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65523 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 0c019c8..80356fa 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,68 @@
+2010-08-17  Jian Li  <jianli at chromium.org>
+
+        Reviewed by David Levin.
+
+        Change FileStream implementation to prepare for blob resource handling.
+        https://bugs.webkit.org/show_bug.cgi?id=43985
+
+        Change FileStream to support synchronous usage only. All the asychronous
+        logics are moved to FileStreamProxy. Update the existing FileReader code
+        to adapt to this change.
+
+        * html/FileReader.cpp: Account for FileStreamProxy changes.
+        (WebCore::FileReader::didStart):
+        (WebCore::FileReader::didGetSize):
+        (WebCore::FileReader::didOpen):
+        (WebCore::FileReader::didRead):
+        * html/FileReader.h:
+        * html/FileStream.cpp: Remove m_client and make all calls synchronous only.
+        (WebCore::FileStream::FileStream):
+        (WebCore::FileStream::start):
+        (WebCore::FileStream::stop):
+        (WebCore::FileStream::getSize):
+        (WebCore::FileStream::openForRead):
+        (WebCore::FileStream::openForWrite):
+        (WebCore::FileStream::close):
+        (WebCore::FileStream::read):
+        (WebCore::FileStream::write):
+        (WebCore::FileStream::truncate):
+        * html/FileStream.h: Add getSize() and make all calls synchronous by adding return values.
+        (WebCore::FileStream::create):
+        * html/FileStreamClient.h: Account for FileStreamProxy changes.
+        (WebCore::FileStreamClient::didRead):
+        (WebCore::FileStreamClient::didTruncate):
+        (WebCore::FileStreamClient::didOpen):
+        * html/FileStreamProxy.cpp: All the logics to handle asynchronous calls are wrapped here.
+        (WebCore::FileStreamProxy::FileStreamProxy):
+        (WebCore::FileStreamProxy::create):
+        (WebCore::FileStreamProxy::fileThread):
+        (WebCore::didStart):
+        (WebCore::FileStreamProxy::startOnFileThread):
+        (WebCore::FileStreamProxy::stop):
+        (WebCore::derefProxyOnContext):
+        (WebCore::FileStreamProxy::stopOnFileThread):
+        (WebCore::didGetSize):
+        (WebCore::FileStreamProxy::getSize):
+        (WebCore::FileStreamProxy::getSizeOnFileThread):
+        (WebCore::didOpen):
+        (WebCore::FileStreamProxy::openForRead):
+        (WebCore::FileStreamProxy::openForReadOnFileThread):
+        (WebCore::FileStreamProxy::openForWrite):
+        (WebCore::FileStreamProxy::openForWriteOnFileThread):
+        (WebCore::FileStreamProxy::close):
+        (WebCore::FileStreamProxy::closeOnFileThread):
+        (WebCore::didRead):
+        (WebCore::FileStreamProxy::read):
+        (WebCore::FileStreamProxy::readOnFileThread):
+        (WebCore::didWrite):
+        (WebCore::FileStreamProxy::write):
+        (WebCore::FileStreamProxy::writeOnFileThread):
+        (WebCore::didTruncate):
+        (WebCore::FileStreamProxy::truncate):
+        (WebCore::FileStreamProxy::truncateOnFileThread):
+        * html/FileStreamProxy.h:
+        * html/FileThreadTask.h: Change all methods to return void since return value is not needed now.
+
 2010-08-17  Dimitri Glazkov  <dglazkov at chromium.org>
 
         Returned WebCore.xcodeproj to default settings after http://trac.webkit.org/changeset/65468/trunk/WebCore/WebCore.xcodeproj/project.pbxproj.
diff --git a/WebCore/html/FileReader.cpp b/WebCore/html/FileReader.cpp
index 6e568ec..e99fdc4 100644
--- a/WebCore/html/FileReader.cpp
+++ b/WebCore/html/FileReader.cpp
@@ -160,33 +160,70 @@ void FileReader::terminate()
 void FileReader::didStart()
 {
     m_state = Opening;
-    m_streamProxy->openForRead(m_fileBlob.get());
+
+    ASSERT(m_fileBlob->items().size() == 1 && m_fileBlob->items().at(0)->toFileBlobItem());
+    const FileRangeBlobItem* fileRangeItem = m_fileBlob->items().at(0)->toFileRangeBlobItem();
+    double expectedModificationTime = fileRangeItem ? fileRangeItem->snapshotModificationTime() : 0;
+
+    m_streamProxy->getSize(m_fileBlob->path(), expectedModificationTime);
 }
 
 void FileReader::didGetSize(long long size)
 {
+    // If the size is -1, it means the file has been moved or changed. Fail now.
+    if (size == -1) {
+        didFail(NOT_FOUND_ERR);
+        return;
+    }
+
     m_state = Reading;
     fireEvent(eventNames().loadstartEvent);
 
-    m_totalBytes = size;
-    m_streamProxy->read(&m_buffer.at(0), m_buffer.size());
+    ASSERT(m_fileBlob->items().size() == 1 && m_fileBlob->items().at(0)->toFileBlobItem());
+    const FileRangeBlobItem* fileRangeItem = m_fileBlob->items().at(0)->toFileRangeBlobItem();
+    long long start = fileRangeItem ? fileRangeItem->start() : 0;
+
+    // The size passed back is the size of the whole file. If the underlying item is a sliced file, we need to use the slice length.
+    m_totalBytes = fileRangeItem ? fileRangeItem->size() : size;
+
+    m_streamProxy->openForRead(m_fileBlob->path(), start, m_totalBytes);
 }
 
-void FileReader::didRead(const char* data, int bytesRead)
+void FileReader::didOpen(ExceptionCode ec)
 {
-    ASSERT(data && bytesRead);
+    if (ec) {
+        didFail(ec);
+        return;
+    }
+    
+    m_streamProxy->read(m_buffer.data(), m_buffer.size());
+}
 
+void FileReader::didRead(int bytesRead)
+{
     // Bail out if we have aborted the reading.
     if (m_state == Completed)
-      return;
+        return;
+
+    // If bytesRead is -1, it means an error happens.
+    if (bytesRead == -1) {
+        didFail(NOT_READABLE_ERR);
+        return;
+    }
+
+    // If bytesRead is 0, it means the reading is done.
+    if (!bytesRead) {
+        didFinish();
+        return;
+    }
 
     switch (m_readType) {
     case ReadFileAsBinaryString:
-        m_result += String(data, static_cast<unsigned>(bytesRead));
+        m_result += String(m_buffer.data(), static_cast<unsigned>(bytesRead));
         break;
     case ReadFileAsText:
     case ReadFileAsDataURL:
-        m_rawData.append(data, static_cast<unsigned>(bytesRead));
+        m_rawData.append(m_buffer.data(), static_cast<unsigned>(bytesRead));
         m_isRawDataConverted = false;
         break;
     default:
@@ -205,7 +242,7 @@ void FileReader::didRead(const char* data, int bytesRead)
     }
 
     // Continue reading.
-    m_streamProxy->read(&m_buffer.at(0), m_buffer.size());
+    m_streamProxy->read(m_buffer.data(), m_buffer.size());
 }
 
 void FileReader::didFinish()
diff --git a/WebCore/html/FileReader.h b/WebCore/html/FileReader.h
index 7952468..2237af5 100644
--- a/WebCore/html/FileReader.h
+++ b/WebCore/html/FileReader.h
@@ -89,9 +89,8 @@ public:
     // FileStreamClient
     virtual void didStart();
     virtual void didGetSize(long long);
-    virtual void didRead(const char*, int);
-    virtual void didFinish();
-    virtual void didFail(ExceptionCode);
+    virtual void didOpen(ExceptionCode);
+    virtual void didRead(int);
 
     using RefCounted<FileReader>::ref;
     using RefCounted<FileReader>::deref;
@@ -130,6 +129,8 @@ private:
     void fireEvent(const AtomicString& type);
     void convertToText();
     void convertToDataURL();
+    void didFinish();
+    void didFail(ExceptionCode);
 
     InternalState m_state;
     EventTargetData m_eventTargetData;
diff --git a/WebCore/html/FileStream.cpp b/WebCore/html/FileStream.cpp
index abe7bad..a89c67a 100644
--- a/WebCore/html/FileStream.cpp
+++ b/WebCore/html/FileStream.cpp
@@ -39,9 +39,8 @@
 
 namespace WebCore {
 
-FileStream::FileStream(FileStreamClient* client)
-    : m_client(client)
-    , m_handle(invalidPlatformFileHandle)
+FileStream::FileStream()
+    : m_handle(invalidPlatformFileHandle)
     , m_bytesProcessed(0)
     , m_totalBytesToRead(0)
 {
@@ -52,130 +51,99 @@ FileStream::~FileStream()
     ASSERT(!isHandleValid(m_handle));
 }
 
+// FIXME: To be removed when we switch to using BlobData.
 void FileStream::start()
 {
-    ASSERT(!isMainThread());
-    m_client->didStart();
 }
 
 void FileStream::stop()
 {
-    ASSERT(!isMainThread());
     close();
-    m_client->didStop();
 }
 
-void FileStream::openForRead(Blob* blob)
+long long FileStream::getSize(const String& path, double expectedModificationTime)
 {
-    ASSERT(!isMainThread());
+    // Check the modification time for the possible file change.
+    time_t modificationTime;
+    if (!getFileModificationTime(path, modificationTime))
+        return -1;
+    if (expectedModificationTime) {
+        if (static_cast<time_t>(expectedModificationTime) != modificationTime)
+            return -1;
+    }
+
+    // Now get the file size.
+    long long length;
+    if (!getFileSize(path, length))
+        return -1;
+
+    return length;
+}
 
+ExceptionCode FileStream::openForRead(const String& path, long long offset, long long length)
+{
     if (isHandleValid(m_handle))
-        return;
-
-    // FIXME: Need to handle multiple items that may include non-file ones when BlobBuilder is introduced.
-    ASSERT(blob->items().size() >= 1);
-    const FileBlobItem* fileItem = blob->items().at(0)->toFileBlobItem();
-    if (!fileItem) {
-        ASSERT(false);
-        m_client->didFail(NOT_READABLE_ERR);
-        return;
-    }
+        return 0;
 
-    // Check if the file exists by querying its modification time. We choose not to call fileExists() in order to save an
-    // extra file system call when the modification time is needed to check the validity of the sliced file blob.
-    // Per the spec, we need to return different error codes to differentiate between non-existent file and permission error.
-    // openFile() could not tell use the failure reason.
-    time_t currentModificationTime;
-    if (!getFileModificationTime(fileItem->path(), currentModificationTime)) {
-        m_client->didFail(NOT_FOUND_ERR);
-        return;
-    }
+    // Open the file.
+    m_handle = openFile(path, OpenForRead);
+    if (!isHandleValid(m_handle))
+        return NOT_READABLE_ERR;
 
-    // Open the file blob.
-    m_handle = openFile(fileItem->path(), OpenForRead);
-    if (!isHandleValid(m_handle)) {
-        m_client->didFail(NOT_READABLE_ERR);
-        return;
+    // Jump to the beginning position if the file has been sliced.
+    if (offset > 0) {
+        if (seekFile(m_handle, offset, SeekFromBeginning) < 0)
+            return NOT_READABLE_ERR;
     }
 
-    const FileRangeBlobItem* fileRangeItem = fileItem->toFileRangeBlobItem();
-    if (fileRangeItem) {
-        // Check the modificationt time for the possible file change.
-        if (static_cast<time_t>(fileRangeItem->snapshotModificationTime()) != currentModificationTime) {
-            m_client->didFail(NOT_READABLE_ERR);
-            return;
-        }
-
-        // Jump to the beginning position if the file has been sliced.
-        if (fileRangeItem->start() > 0) {
-            if (seekFile(m_handle, fileRangeItem->start(), SeekFromBeginning) < 0) {
-                m_client->didFail(NOT_READABLE_ERR);
-                return;
-            }
-        }
-    }
+    m_totalBytesToRead = length;
+    m_bytesProcessed = 0;
 
-    // Get the size.
-    m_totalBytesToRead = blob->size();
-    m_client->didGetSize(m_totalBytesToRead);
+    return 0;
 }
 
-void FileStream::openForWrite(const String&)
+ExceptionCode FileStream::openForWrite(const String&)
 {
-    ASSERT(!isMainThread());
     // FIXME: to be implemented.
+    return NOT_SUPPORTED_ERR;
 }
 
 void FileStream::close()
 {
-    ASSERT(!isMainThread());
     if (isHandleValid(m_handle)) {
         closeFile(m_handle);
         m_handle = invalidPlatformFileHandle;
     }
 }
 
-void FileStream::read(char* buffer, int length)
+int FileStream::read(char* buffer, int bufferSize)
 {
-    ASSERT(!isMainThread());
-
-    if (!isHandleValid(m_handle)) {
-        m_client->didFail(NOT_READABLE_ERR);
-        return;
-    }
-
-    if (m_bytesProcessed >= m_totalBytesToRead) {
-        m_client->didFinish();
-        return;
-    }
+    if (!isHandleValid(m_handle))
+        return -1;
 
     long long remaining = m_totalBytesToRead - m_bytesProcessed;
-    int bytesToRead = (remaining < length) ? static_cast<int>(remaining) : length;
-    int bytesRead = readFromFile(m_handle, buffer, bytesToRead);
-    if (bytesRead < 0) {
-        m_client->didFail(NOT_READABLE_ERR);
-        return;
-    }
-
-    if (!bytesRead) {
-        m_client->didFinish();
-        return;
-    }
-
-    m_bytesProcessed += bytesRead;
-    m_client->didRead(buffer, bytesRead);
+    int bytesToRead = (remaining < bufferSize) ? static_cast<int>(remaining) : bufferSize;
+    int bytesRead = 0;
+    if (bytesToRead > 0)
+        bytesRead = readFromFile(m_handle, buffer, bytesToRead);
+    if (bytesRead < 0)
+        return -1;
+    if (bytesRead > 0)
+        m_bytesProcessed += bytesRead;
+
+    return bytesRead;
 }
 
-void FileStream::write(Blob*, long long, int)
+int FileStream::write(Blob*, long long, int)
 {
-    ASSERT(!isMainThread());
     // FIXME: to be implemented.
+    return -1;
 }
 
-void FileStream::truncate(long long)
+ExceptionCode FileStream::truncate(long long)
 {
-    ASSERT(!isMainThread());
     // FIXME: to be implemented.
+    return NOT_SUPPORTED_ERR;
 }
 
 } // namespace WebCore
diff --git a/WebCore/html/FileStream.h b/WebCore/html/FileStream.h
index b5eccd4..e299fe4 100644
--- a/WebCore/html/FileStream.h
+++ b/WebCore/html/FileStream.h
@@ -33,7 +33,7 @@
 
 #if ENABLE(BLOB) || ENABLE(FILE_WRITER)
 
-#include "FileStreamClient.h"
+#include "ExceptionCode.h"
 #include "FileSystem.h"
 #include <wtf/Forward.h>
 #include <wtf/PassRefPtr.h>
@@ -43,29 +43,52 @@ namespace WebCore {
 
 class Blob;
 
-// All methods are synchronous and should be called on File or Worker thread.
+// All methods are synchronous.
 class FileStream : public RefCounted<FileStream> {
 public:
-    static PassRefPtr<FileStream> create(FileStreamClient* client)
+    static PassRefPtr<FileStream> create()
     {
-        return adoptRef(new FileStream(client));
+        return adoptRef(new FileStream());
     }
     virtual ~FileStream();
 
+    // FIXME: To be removed when we switch to using BlobData.
     void start();
+
+    // Aborts the operation.
     void stop();
 
-    void openForRead(Blob*);
-    void openForWrite(const String& path);
+    // Gets the size of a file. Also validates if the file has been changed or not if the expected modification time is provided, i.e. non-zero.
+    // Returns total number of bytes if successful. -1 otherwise.
+    long long getSize(const String& path, double expectedModificationTime);
+
+    // Opens a file for reading. The reading starts at the specified offset and lasts till the specified length.
+    // Returns 0 on success. Exception code otherwise.
+    ExceptionCode openForRead(const String& path, long long offset, long long length);
+
+    // Opens a file for writing.
+    // Returns 0 on success. Exception code otherwise.
+    ExceptionCode openForWrite(const String& path);
+
+    // Closes the file.
     void close();
-    void read(char* buffer, int length);
-    void write(Blob* blob, long long position, int length);
-    void truncate(long long position);
+
+    // Reads a file into the provided data buffer.
+    // Returns number of bytes being read on success. -1 otherwise.
+    // If 0 is returned, it means that the reading is completed.
+    int read(char* buffer, int length);
+
+    // Writes a blob to the file.
+    // Returns number of bytes being written on success. -1 otherwise.
+    int write(Blob*, long long position, int length);
+
+    // Truncates the file to the specified position.
+    // Returns 0 on success. Exception code otherwise.
+    ExceptionCode truncate(long long position);
 
 private:
-    FileStream(FileStreamClient*);
+    FileStream();
 
-    FileStreamClient* m_client;
     PlatformFileHandle m_handle;
     long long m_bytesProcessed;
     long long m_totalBytesToRead;
diff --git a/WebCore/html/FileStreamClient.h b/WebCore/html/FileStreamClient.h
index 2e7091f..440d2fb 100644
--- a/WebCore/html/FileStreamClient.h
+++ b/WebCore/html/FileStreamClient.h
@@ -40,16 +40,18 @@ namespace WebCore {
 class FileStreamClient {
 public:
     // For reading.
-    virtual void didRead(const char*, int) { }
+    virtual void didRead(int) { }
 
     // For writing.
     virtual void didWrite(int) { }
+    virtual void didTruncate(ExceptionCode) { }
 
-    // For both reading and writing.
+    // FIXME: To be removed when we switch to using BlobData.
     virtual void didStart() { }
+
+    // For both reading and writing.
+    virtual void didOpen(ExceptionCode) { }
     virtual void didStop() { }
-    virtual void didFinish() { }
-    virtual void didFail(ExceptionCode) { }
     virtual void didGetSize(long long) { }
 
 protected:
diff --git a/WebCore/html/FileStreamProxy.cpp b/WebCore/html/FileStreamProxy.cpp
index e3b9e79..f50b7e8 100644
--- a/WebCore/html/FileStreamProxy.cpp
+++ b/WebCore/html/FileStreamProxy.cpp
@@ -37,6 +37,7 @@
 #include "Blob.h"
 #include "CrossThreadTask.h"
 #include "FileStream.h"
+#include "FileStreamClient.h"
 #include "FileThread.h"
 #include "FileThreadTask.h"
 #include "PlatformString.h"
@@ -47,7 +48,7 @@ namespace WebCore {
 inline FileStreamProxy::FileStreamProxy(ScriptExecutionContext* context, FileStreamClient* client)
     : m_context(context)
     , m_client(client)
-    , m_stream(FileStream::create(this))
+    , m_stream(FileStream::create())
 {
 }
 
@@ -59,7 +60,7 @@ PassRefPtr<FileStreamProxy> FileStreamProxy::create(ScriptExecutionContext* cont
     // This is balanced by the deref in derefProxyOnContext below.
     proxy->ref();
 
-    proxy->fileThread()->postTask(createFileThreadTask(proxy->m_stream.get(), &FileStream::start));
+    proxy->fileThread()->postTask(createFileThreadTask(proxy.get(), &FileStreamProxy::startOnFileThread));
 
     return proxy.release();
 }
@@ -68,133 +69,150 @@ FileStreamProxy::~FileStreamProxy()
 {
 }
 
-void FileStreamProxy::openForRead(Blob* blob)
+FileThread* FileStreamProxy::fileThread()
 {
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::openForRead, blob));
+    ASSERT(m_context->isContextThread());
+    ASSERT(m_context->fileThread());
+    return m_context->fileThread();
 }
 
-void FileStreamProxy::openForWrite(const String& path)
+static void didStart(ScriptExecutionContext*, FileStreamProxy* proxy)
 {
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::openForWrite, path));
+    if (proxy->client())
+        proxy->client()->didStart();
 }
 
-void FileStreamProxy::close()
+void FileStreamProxy::startOnFileThread()
 {
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::close));
+    m_stream->start();
+    m_context->postTask(createCallbackTask(&didStart, this));
 }
 
-void FileStreamProxy::read(char* buffer, int length)
+void FileStreamProxy::stop()
 {
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::read, buffer, length));
+    // Clear the client so that we won't be calling callbacks on the client.
+    m_client = 0;
+
+    fileThread()->unscheduleTasks(m_stream.get());
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::stopOnFileThread));
 }
 
-void FileStreamProxy::write(Blob* blob, long long position, int length)
+static void derefProxyOnContext(ScriptExecutionContext*, FileStreamProxy* proxy)
 {
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::write, blob, position, length));
+    ASSERT(proxy->hasOneRef());
+    proxy->deref();
 }
 
-void FileStreamProxy::truncate(long long position)
+void FileStreamProxy::stopOnFileThread()
 {
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::truncate, position));
+    m_stream->stop();
+    m_context->postTask(createCallbackTask(&derefProxyOnContext, this));
 }
 
-FileThread* FileStreamProxy::fileThread()
+static void didGetSize(ScriptExecutionContext*, FileStreamProxy* proxy, long long size)
 {
-    ASSERT(m_context->isContextThread());
-    ASSERT(m_context->fileThread());
-    return m_context->fileThread();
+    if (proxy->client())
+        proxy->client()->didGetSize(size);
 }
 
-void FileStreamProxy::stop()
+void FileStreamProxy::getSize(const String& path, double expectedModificationTime)
 {
-    // Clear the client so that we won't be calling callbacks on the client.
-    m_client = 0;
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::getSizeOnFileThread, path, expectedModificationTime));
+}
 
-    fileThread()->unscheduleTasks(m_stream.get());
-    fileThread()->postTask(createFileThreadTask(m_stream.get(), &FileStream::stop));
+void FileStreamProxy::getSizeOnFileThread(const String& path, double expectedModificationTime)
+{
+    long long size = m_stream->getSize(path, expectedModificationTime);
+    m_context->postTask(createCallbackTask(&didGetSize, this, size));
 }
 
-static void notifyGetSizeOnContext(ScriptExecutionContext*, FileStreamProxy* proxy, long long size)
+static void didOpen(ScriptExecutionContext*, FileStreamProxy* proxy, ExceptionCode ec)
 {
     if (proxy->client())
-        proxy->client()->didGetSize(size);
+        proxy->client()->didOpen(ec);
 }
 
-void FileStreamProxy::didGetSize(long long size)
+void FileStreamProxy::openForRead(const String& path, long long offset, long long length)
 {
-    ASSERT(!m_context->isContextThread());
-    m_context->postTask(createCallbackTask(&notifyGetSizeOnContext, this, size));
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::openForReadOnFileThread, path, offset, length));
 }
 
-static void notifyReadOnContext(ScriptExecutionContext*, FileStreamProxy* proxy, const char* data, int bytesRead)
+void FileStreamProxy::openForReadOnFileThread(const String& path, long long offset, long long length)
 {
-    if (proxy->client())
-        proxy->client()->didRead(data, bytesRead);
+    ExceptionCode ec = m_stream->openForRead(path, offset, length);
+    m_context->postTask(createCallbackTask(&didOpen, this, ec));
+}
+
+void FileStreamProxy::openForWrite(const String& path)
+{
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::openForWriteOnFileThread, path));
 }
 
-void FileStreamProxy::didRead(const char* data, int bytesRead)
+void FileStreamProxy::openForWriteOnFileThread(const String& path)
 {
-    ASSERT(!m_context->isContextThread());
-    m_context->postTask(createCallbackTask(&notifyReadOnContext, this, data, bytesRead));
+    ExceptionCode ec = m_stream->openForWrite(path);
+    m_context->postTask(createCallbackTask(&didOpen, this, ec));
 }
 
-static void notifyWriteOnContext(ScriptExecutionContext*, FileStreamProxy* proxy, int bytesWritten)
+void FileStreamProxy::close()
 {
-    if (proxy->client())
-        proxy->client()->didWrite(bytesWritten);
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::closeOnFileThread));
 }
 
-void FileStreamProxy::didWrite(int bytesWritten)
+void FileStreamProxy::closeOnFileThread()
 {
-    ASSERT(!m_context->isContextThread());
-    m_context->postTask(createCallbackTask(&notifyWriteOnContext, this, bytesWritten));
+    m_stream->close();
 }
 
-static void notifyStartOnContext(ScriptExecutionContext*, FileStreamProxy* proxy)
+static void didRead(ScriptExecutionContext*, FileStreamProxy* proxy, int bytesRead)
 {
     if (proxy->client())
-        proxy->client()->didStart();
+        proxy->client()->didRead(bytesRead);
 }
 
-void FileStreamProxy::didStart()
+void FileStreamProxy::read(char* buffer, int length)
+{
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::readOnFileThread, buffer, length));
+}
+
+void FileStreamProxy::readOnFileThread(char* buffer, int length)
 {
-    ASSERT(!m_context->isContextThread());
-    m_context->postTask(createCallbackTask(&notifyStartOnContext, this));
+    int bytesRead = m_stream->read(buffer, length);
+    m_context->postTask(createCallbackTask(&didRead, this, bytesRead));
 }
 
-static void notifyFinishOnContext(ScriptExecutionContext*, FileStreamProxy* proxy)
+static void didWrite(ScriptExecutionContext*, FileStreamProxy* proxy, int bytesWritten)
 {
     if (proxy->client())
-        proxy->client()->didFinish();
+        proxy->client()->didWrite(bytesWritten);
 }
 
-void FileStreamProxy::didFinish()
+void FileStreamProxy::write(Blob* blob, long long position, int length)
 {
-    ASSERT(!m_context->isContextThread());
-    m_context->postTask(createCallbackTask(&notifyFinishOnContext, this));
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::writeOnFileThread, blob, position, length));
 }
 
-static void notifyFailOnContext(ScriptExecutionContext*, FileStreamProxy* proxy, ExceptionCode ec)
+void FileStreamProxy::writeOnFileThread(Blob* blob, long long position, int length)
 {
-    if (proxy->client())
-        proxy->client()->didFail(ec);
+    int bytesWritten = m_stream->write(blob, position, length);
+    m_context->postTask(createCallbackTask(&didWrite, this, bytesWritten));
 }
 
-void FileStreamProxy::didFail(ExceptionCode ec)
+static void didTruncate(ScriptExecutionContext*, FileStreamProxy* proxy, ExceptionCode ec)
 {
-    ASSERT(!m_context->isContextThread());
-    m_context->postTask(createCallbackTask(&notifyFailOnContext, this, ec));
+    if (proxy->client())
+        proxy->client()->didTruncate(ec);
 }
 
-static void derefProxyOnContext(ScriptExecutionContext*, FileStreamProxy* proxy)
+void FileStreamProxy::truncate(long long position)
 {
-    ASSERT(proxy->hasOneRef());
-    proxy->deref();
+    fileThread()->postTask(createFileThreadTask(this, &FileStreamProxy::truncateOnFileThread, position));
 }
 
-void FileStreamProxy::didStop()
+void FileStreamProxy::truncateOnFileThread(long long position)
 {
-    m_context->postTask(createCallbackTask(&derefProxyOnContext, this));
+    ExceptionCode ec = m_stream->truncate(position);
+    m_context->postTask(createCallbackTask(&didTruncate, this, ec));
 }
 
 } // namespace WebCore
diff --git a/WebCore/html/FileStreamProxy.h b/WebCore/html/FileStreamProxy.h
index 8523d4a..1d03a58 100644
--- a/WebCore/html/FileStreamProxy.h
+++ b/WebCore/html/FileStreamProxy.h
@@ -34,7 +34,6 @@
 
 #if ENABLE(BLOB) || ENABLE(FILE_WRITER)
 
-#include "FileStreamClient.h"
 #include <wtf/Forward.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -44,20 +43,22 @@ namespace WebCore {
 
 class Blob;
 class FileStream;
+class FileStreamClient;
 class FileThread;
 class ScriptExecutionContext;
 
-// A proxy module that calls corresponding FileStream methods on the file thread.  Note: you must call stop() first and then release the reference to destruct the FileStreamProxy instance.
-class FileStreamProxy : public RefCounted<FileStreamProxy>, public FileStreamClient {
+// A proxy module that asynchronously calls corresponding FileStream methods on the file thread.  Note: you must call stop() first and then release the reference to destruct the FileStreamProxy instance.
+class FileStreamProxy : public RefCounted<FileStreamProxy> {
 public:
     static PassRefPtr<FileStreamProxy> create(ScriptExecutionContext*, FileStreamClient*);
     virtual ~FileStreamProxy();
 
-    void openForRead(Blob* blob);
+    void getSize(const String& path, double expectedModificationTime);
+    void openForRead(const String& path, long long offset, long long length);
     void openForWrite(const String& path);
     void close();
     void read(char* buffer, int length);
-    void write(Blob* blob, long long position, int length);
+    void write(Blob*, long long position, int length);
     void truncate(long long position);
 
     // Stops the proxy and scedules it to be destructed.  All the pending tasks will be aborted and the file stream will be closed.
@@ -69,17 +70,19 @@ public:
 private:
     FileStreamProxy(ScriptExecutionContext*, FileStreamClient*);
 
-    // FileStreamClient methods.
-    virtual void didGetSize(long long);
-    virtual void didRead(const char*, int);
-    virtual void didWrite(int);
-    virtual void didFinish();
-    virtual void didFail(ExceptionCode);
-    virtual void didStart();
-    virtual void didStop();
-
     FileThread* fileThread();
 
+    // Called on File thread.
+    void startOnFileThread();
+    void stopOnFileThread();
+    void getSizeOnFileThread(const String& path, double expectedModificationTime);
+    void openForReadOnFileThread(const String& path, long long offset, long long length);
+    void openForWriteOnFileThread(const String& path);
+    void closeOnFileThread();
+    void readOnFileThread(char* buffer, int length);
+    void writeOnFileThread(Blob*, long long position, int length);
+    void truncateOnFileThread(long long position);
+
     RefPtr<ScriptExecutionContext> m_context;
     FileStreamClient* m_client;
     RefPtr<FileStream> m_stream;
diff --git a/WebCore/html/FileThreadTask.h b/WebCore/html/FileThreadTask.h
index 09b647f..3443457 100644
--- a/WebCore/html/FileThreadTask.h
+++ b/WebCore/html/FileThreadTask.h
@@ -39,11 +39,11 @@
 
 namespace WebCore {
 
-template<typename R, typename T>
+template<typename T>
 class FileThreadTask0 : public FileThread::Task {
 public:
-    typedef R (T::*Method)();
-    typedef FileThreadTask0<R, T> FileThreadTaskImpl;
+    typedef void (T::*Method)();
+    typedef FileThreadTask0<T> FileThreadTaskImpl;
 
     static PassOwnPtr<FileThreadTaskImpl> create(T* instance, Method method)
     {
@@ -66,11 +66,11 @@ private:
     Method m_method;
 };
 
-template<typename R, typename T, typename P1, typename MP1>
+template<typename T, typename P1, typename MP1>
 class FileThreadTask1 : public FileThread::Task {
 public:
-    typedef R (T::*Method)(MP1);
-    typedef FileThreadTask1<R, T, P1, MP1> FileThreadTaskImpl;
+    typedef void (T::*Method)(MP1);
+    typedef FileThreadTask1<T, P1, MP1> FileThreadTaskImpl;
     typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
 
     static PassOwnPtr<FileThreadTaskImpl> create(T* instance, Method method, Param1 parameter1)
@@ -96,11 +96,11 @@ private:
     P1 m_parameter1;
 };
 
-template<typename R, typename T, typename P1, typename MP1, typename P2, typename MP2>
+template<typename T, typename P1, typename MP1, typename P2, typename MP2>
 class FileThreadTask2 : public FileThread::Task {
 public:
-    typedef R (T::*Method)(MP1, MP2);
-    typedef FileThreadTask2<R, T, P1, MP1, P2, MP2> FileThreadTaskImpl;
+    typedef void (T::*Method)(MP1, MP2);
+    typedef FileThreadTask2<T, P1, MP1, P2, MP2> FileThreadTaskImpl;
     typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
     typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
 
@@ -129,11 +129,11 @@ private:
     P2 m_parameter2;
 };
 
-template<typename R, typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
 class FileThreadTask3 : public FileThread::Task {
 public:
     typedef void (T::*Method)(MP1, MP2, MP3);
-    typedef FileThreadTask3<R, T, P1, MP1, P2, MP2, P3, MP3> FileThreadTaskImpl;
+    typedef FileThreadTask3<T, P1, MP1, P2, MP2, P3, MP3> FileThreadTaskImpl;
     typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
     typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
     typedef typename CrossThreadTaskTraits<P3>::ParamType Param3;
@@ -165,56 +165,56 @@ private:
     P3 m_parameter3;
 };
 
-template<typename R, typename T>
+template<typename T>
 PassOwnPtr<FileThread::Task> createFileThreadTask(
     T* const callee,
-    R (T::*method)());
+    void (T::*method)());
 
-template<typename R, typename T>
+template<typename T>
 PassOwnPtr<FileThread::Task> createFileThreadTask(
     T* const callee,
-    R (T::*method)())
+    void (T::*method)())
 {
-    return FileThreadTask0<R, T>::create(
+    return FileThreadTask0<T>::create(
         callee,
         method);
 }
 
-template<typename R, typename T, typename P1, typename MP1>
+template<typename T, typename P1, typename MP1>
 PassOwnPtr<FileThread::Task> createFileThreadTask(
     T* const callee,
-    R (T::*method)(MP1),
+    void (T::*method)(MP1),
     const P1& parameter1)
 {
-    return FileThreadTask1<R, T, typename CrossThreadCopier<P1>::Type, MP1>::create(
+    return FileThreadTask1<T, typename CrossThreadCopier<P1>::Type, MP1>::create(
         callee,
         method,
         CrossThreadCopier<P1>::copy(parameter1));
 }
 
-template<typename R, typename T, typename P1, typename MP1, typename P2, typename MP2>
+template<typename T, typename P1, typename MP1, typename P2, typename MP2>
 PassOwnPtr<FileThread::Task> createFileThreadTask(
     T* const callee,
-    R (T::*method)(MP1, MP2),
+    void (T::*method)(MP1, MP2),
     const P1& parameter1,
     const P2& parameter2)
 {
-    return FileThreadTask2<R, T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2>::create(
+    return FileThreadTask2<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2>::create(
         callee,
         method,
         CrossThreadCopier<P1>::copy(parameter1),
         CrossThreadCopier<P2>::copy(parameter2));
 }
 
-template<typename R, typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
 PassOwnPtr<FileThread::Task> createFileThreadTask(
     T* const callee,
-    R (T::*method)(MP1, MP2, MP3),
+    void (T::*method)(MP1, MP2, MP3),
     const P1& parameter1,
     const P2& parameter2,
     const P3& parameter3)
 {
-    return FileThreadTask3<R, T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3>::create(
+    return FileThreadTask3<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3>::create(
         callee,
         method,
         CrossThreadCopier<P1>::copy(parameter1),

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list