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

kinuko at chromium.org kinuko at chromium.org
Wed Dec 22 14:20:59 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 3256c0f4da3729e93762e7232ff84eded295eb16
Author: kinuko at chromium.org <kinuko at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Oct 6 23:08:50 2010 +0000

    2010-10-06  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Add FileSystemSync implementation for Worker
            https://bugs.webkit.org/show_bug.cgi?id=47044
    
            * src/LocalFileSystemChromium.cpp:
            (WebCore::LocalFileSystem::requestFileSystem): Added a new parameter
            for synchronous mode.
            * src/WebFileSystemCallbacksImpl.cpp:
            (WebKit::WebFileSystemCallbacksImpl::WebFileSystemCallbacksImpl): Added
            a parameter for synchronous mode.
            (WebKit::WebFileSystemCallbacksImpl::didOpenFileSystem): Changed to
            creates WorkerAsyncFileSystemChromium with synchronous flag.
            * src/WebFileSystemCallbacksImpl.h:
            * src/WebWorkerBase.cpp:
            (WebKit::WebWorkerBase::openFileSystem): Added a parameter for
            synchronous mode.
            * src/WebWorkerBase.h:
            * src/WorkerAsyncFileSystemChromium.cpp:
            (WebCore::WorkerAsyncFileSystemChromium::WorkerAsyncFileSystemChromium):
            (WebCore::WorkerAsyncFileSystemChromium::waitForOperationToComplete):
            Added.
            (WebCore::WorkerAsyncFileSystemChromium::move):
            (WebCore::WorkerAsyncFileSystemChromium::copy):
            (WebCore::WorkerAsyncFileSystemChromium::remove):
            (WebCore::WorkerAsyncFileSystemChromium::readMetadata):
            (WebCore::WorkerAsyncFileSystemChromium::createFile):
            (WebCore::WorkerAsyncFileSystemChromium::createDirectory):
            (WebCore::WorkerAsyncFileSystemChromium::fileExists):
            (WebCore::WorkerAsyncFileSystemChromium::directoryExists):
            (WebCore::WorkerAsyncFileSystemChromium::readDirectory):
            (WebCore::WorkerAsyncFileSystemChromium::createWorkerFileSystemCallbacksBridge):
            Updated to store the created bridge in a member variable so that
            we can call bridge->stop() later when the RunLoop is terminating.
            * src/WorkerAsyncFileSystemChromium.h:
            (WebCore::WorkerAsyncFileSystemChromium::create): Added a new
            parameter for synchronous mode.
    2010-10-06  Andrei Popescu  <andreip at google.com>
    
            Reviewed by Jeremy Orlow.
    
            IDBDatabase and IDBObjectStore metadata is not recovered correctly when the setVersion transactions aborts.
            https://bugs.webkit.org/show_bug.cgi?id=47245
    
            Recover metadata properly by adding abort tasks that
            are run when a transaction aborts.
    
            * storage/IDBDatabase.cpp:
            (WebCore::IDBDatabase::createObjectStore):
            (WebCore::IDBDatabase::removeObjectStore):
            * storage/IDBDatabaseBackendImpl.cpp:
            (WebCore::IDBDatabaseBackendImpl::createObjectStore):
            (WebCore::IDBDatabaseBackendImpl::removeObjectStore):
            (WebCore::IDBDatabaseBackendImpl::setVersion):
            (WebCore::IDBDatabaseBackendImpl::removeObjectStoreFromMap):
            (WebCore::IDBDatabaseBackendImpl::addObjectStoreToMap):
            (WebCore::IDBDatabaseBackendImpl::resetVersion):
            * storage/IDBDatabaseBackendImpl.h:
            * storage/IDBObjectStoreBackendImpl.cpp:
            (WebCore::IDBObjectStoreBackendImpl::createIndex):
            (WebCore::IDBObjectStoreBackendImpl::removeIndex):
            (WebCore::IDBObjectStoreBackendImpl::removeIndexFromMap):
            (WebCore::IDBObjectStoreBackendImpl::addIndexToMap):
            * storage/IDBObjectStoreBackendImpl.h:
            * storage/IDBTransactionBackendImpl.cpp:
            (WebCore::IDBTransactionBackendImpl::scheduleTask):
            (WebCore::IDBTransactionBackendImpl::abort):
            * storage/IDBTransactionBackendImpl.h:
            * storage/IDBTransactionBackendInterface.h:
            * storage/IDBTransactionCoordinator.h:
    2010-10-06  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Add FileSystemSync implementation for Worker
            https://bugs.webkit.org/show_bug.cgi?id=47044
    
            * fast/filesystem/async-operations.html: Added.
            * fast/filesystem/resources/async-operations.js: Added.
            * fast/filesystem/resources/fs-worker-test-pre.js:
            * fast/filesystem/resources/sync-operations.js: Added.
            * fast/filesystem/script-tests/flags-passing.js:
            * fast/filesystem/workers/async-operations-expected.txt: Added.
            * fast/filesystem/workers/async-operations.html: Added.
            * fast/filesystem/workers/simple-persistent-sync-expected.txt:
            * fast/filesystem/workers/simple-temporary-sync-expected.txt:
            * fast/filesystem/workers/sync-operations-expected.txt: Added.
            * fast/filesystem/workers/sync-operations.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69249 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f3d9d56..1ad9273 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2010-10-06  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Add FileSystemSync implementation for Worker
+        https://bugs.webkit.org/show_bug.cgi?id=47044
+
+        * fast/filesystem/async-operations.html: Added.
+        * fast/filesystem/resources/async-operations.js: Added.
+        * fast/filesystem/resources/fs-worker-test-pre.js:
+        * fast/filesystem/resources/sync-operations.js: Added.
+        * fast/filesystem/script-tests/flags-passing.js:
+        * fast/filesystem/workers/async-operations-expected.txt: Added.
+        * fast/filesystem/workers/async-operations.html: Added.
+        * fast/filesystem/workers/simple-persistent-sync-expected.txt:
+        * fast/filesystem/workers/simple-temporary-sync-expected.txt:
+        * fast/filesystem/workers/sync-operations-expected.txt: Added.
+        * fast/filesystem/workers/sync-operations.html: Added.
+
 2010-10-06  Andrei Popescu  <andreip at google.com>
 
         Reviewed by Jeremy Orlow.
diff --git a/LayoutTests/fast/filesystem/async-operations-expected.txt b/LayoutTests/fast/filesystem/async-operations-expected.txt
new file mode 100644
index 0000000..8fd9ead
--- /dev/null
+++ b/LayoutTests/fast/filesystem/async-operations-expected.txt
@@ -0,0 +1,16 @@
+Test making multiple async FileSystem operations.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Got FileSystem:TestShellFileSystem
+requested FileSystem.
+Starting async test stage 1.
+Starting async test stage 2.
+Verifying the FileSystem status.
+PASS "/a,/b,/c,/d2,/e,/f" is "/a,/b,/c,/d2,/e,/f"
+PASS dirsCount is 3
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/filesystem/async-operations.html b/LayoutTests/fast/filesystem/async-operations.html
new file mode 100644
index 0000000..5a82fc0
--- /dev/null
+++ b/LayoutTests/fast/filesystem/async-operations.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="resources/fs-test-util.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/async-operations.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/filesystem/resources/async-operations.js b/LayoutTests/fast/filesystem/resources/async-operations.js
new file mode 100644
index 0000000..5c484fc
--- /dev/null
+++ b/LayoutTests/fast/filesystem/resources/async-operations.js
@@ -0,0 +1,107 @@
+if (this.importScripts) {
+    importScripts('../resources/fs-worker-common.js');
+    importScripts('../resources/fs-test-util.js');
+}
+
+description("Test making multiple async FileSystem operations.");
+
+var fileSystem = null;
+
+var a;
+var b;
+var c;
+var d;
+
+var paths = [];
+var dirsCount = 0;
+var reader = null;
+
+function errorCallback(error) {
+    debug("Got error: " + error.code);
+    removeRecursively(fileSystem.root);
+    finishJSTest();
+}
+
+function entriesCallback(entries) {
+    for (var i = 0; i < entries.length; ++i) {
+        paths.push(entries[i].fullPath);
+        if (entries[i].isDirectory)
+            dirsCount++;
+    }
+    if (!entries.length) {
+        reader.readEntries(entriesCallback, errorCallback);
+    } else {
+        paths.sort();
+        shouldBe('"' + paths.join(',') + '"', '"/a,/b,/c,/d2,/e,/f"');
+        shouldBe("dirsCount", "3");
+        removeRecursively(fileSystem.root);
+        finishJSTest();
+    }
+}
+
+function verify() {
+    debug("Verifying the FileSystem status.");
+    reader = fileSystem.root.createReader();
+    reader.readEntries(entriesCallback, errorCallback);
+}
+
+function asyncTest2() {
+    debug("Starting async test stage 2.");
+
+    var helper = new JoinHelper();
+    var done = function() { helper.done(); };
+
+    helper.run(function() { a.copyTo(b, 'tmp', done, errorCallback); });
+    helper.run(function() { a.getMetadata(done, errorCallback); });
+    helper.run(function() { b.getParent(done, errorCallback); });
+    helper.run(function() { c.copyTo(fileSystem.root, 'f', done, errorCallback); });
+    helper.run(function() { d.moveTo(fileSystem.root, 'd2', done, errorCallback); });
+    helper.run(function() { fileSystem.root.getFile('e', {create:true}, done, errorCallback); });
+
+    helper.join(verify);
+}
+
+function asyncTest1() {
+    debug("Starting async test stage 1.");
+
+    var helper = new JoinHelper();
+    var root = fileSystem.root;
+
+    helper.run(function() { root.getFile('a', {create:true}, function(entry) {
+        a = entry;
+        helper.done();
+    }, errorCallback); });
+
+    helper.run(function() { root.getDirectory('b', {create:true}, function(entry) {
+        b = entry;
+        helper.done();
+    }, errorCallback); });
+
+    helper.run(function() { root.getDirectory('c', {create:true}, function(entry) {
+        c = entry;
+        helper.done();
+    }, errorCallback); });
+
+    helper.run(function() { root.getFile('d', {create:true}, function(entry) {
+        d = entry;
+        helper.done();
+    }, errorCallback); });
+
+    helper.join(asyncTest2);
+}
+
+if (this.requestFileSystem) {
+    jsTestIsAsync = true;
+    var helper = new JoinHelper();
+    helper.run(function() {
+    requestFileSystem.apply(this, [this.TEMPORARY, 100, function(fs) {
+        debug("Got FileSystem:" + fs.name);
+        fileSystem = fs;
+        removeRecursively(fileSystem.root, function(){ helper.done(); }, errorCallback);
+    }, errorCallback]); });
+    debug("requested FileSystem.");
+    helper.join(asyncTest1);
+} else
+    debug("This test requires FileSystem API support.");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/filesystem/resources/fs-test-util.js b/LayoutTests/fast/filesystem/resources/fs-test-util.js
index 9eddcb5..98768ce 100644
--- a/LayoutTests/fast/filesystem/resources/fs-test-util.js
+++ b/LayoutTests/fast/filesystem/resources/fs-test-util.js
@@ -1,3 +1,13 @@
+function bindCallback(obj, callback, arg1, arg2, arg3)
+{
+    return function(arg) {
+        if (arg == undefined)
+            callback.apply(obj, [arg1, arg2, arg3]);
+        else
+            callback.apply(obj, [arg, arg1, arg2, arg3]);
+    };
+}
+
 // Usage:
 //   var helper = new JoinHelper;
 //
@@ -55,22 +65,11 @@ function removeRecursively(directory, successCallback, errorCallback) {
             return false;
         };
 
-        this.bind = function(callback, arg1, arg2, arg3)
-        {
-            var obj = this;
-            return function(arg) {
-                if (arg == undefined)
-                    callback.apply(obj, [arg1, arg2, arg3]);
-                else
-                    callback.apply(obj, [arg, arg1, arg2, arg3]);
-            };
-        };
-
         this.removeDirectory = function(directory, parentDirectory)
         {
             if (directory.fullPath != '/') {
                 // Ok to remove the parent directory.
-                directory.remove(this.bind(this.entryRemovedCallback, parentDirectory, directory), this.bind(this.ErrorCallback));
+                directory.remove(bindCallback(this, this.entryRemovedCallback, parentDirectory, directory), bindCallback(this, this.ErrorCallback));
             } else
                 delete this.removeDirMap[directory.fullPath];
             if (!this.hasMoreEntries(this.removeDirMap) && this.successCallback)
@@ -97,11 +96,11 @@ function removeRecursively(directory, successCallback, errorCallback) {
                     this.removeRecursivelyInternal(entries[i], directory);
                 else {
                     var entry = entries[i];
-                    entry.remove(this.bind(this.entryRemovedCallback, directory, entry), this.bind(this.errorCallback));
+                    entry.remove(bindCallback(this, this.entryRemovedCallback, directory, entry), bindCallback(this, this.errorCallback));
                 }
             }
             if (entries.length) {
-                this.removeDirMap[directory.fullPath].reader.readEntries(this.bind(this.removeRecursivelyCallback, directory), this.bind(this.errorCallback));
+                this.removeDirMap[directory.fullPath].reader.readEntries(bindCallback(this, this.removeRecursivelyCallback, directory), bindCallback(this, this.errorCallback));
             } else {
                 var dirInfo = this.removeDirMap[directory.fullPath];
                 dirInfo.hasMore = false;
@@ -119,7 +118,7 @@ function removeRecursively(directory, successCallback, errorCallback) {
                 entries: 0,
                 reader: directoryReader,
             };
-            directoryReader.readEntries(this.bind(this.removeRecursivelyCallback, directory), this.bind(this.errorCallback));
+            directoryReader.readEntries(bindCallback(this, this.removeRecursivelyCallback, directory), bindCallback(this, this.errorCallback));
         };
     };
 
diff --git a/LayoutTests/fast/filesystem/resources/fs-worker-common.js b/LayoutTests/fast/filesystem/resources/fs-worker-common.js
index a2ba1f1..ea9a194 100644
--- a/LayoutTests/fast/filesystem/resources/fs-worker-common.js
+++ b/LayoutTests/fast/filesystem/resources/fs-worker-common.js
@@ -27,11 +27,24 @@ function shouldBe(_a, _b)
 
 function shouldBeTrue(_a) { shouldBe(_a, "true"); }
 
+function removeRecursivelySync(directory) {
+    if (!directory)
+        return;
+    var reader = directory.createReader();
+    do {
+        var entries = reader.readEntries();
+        for (var i = 0; i < entries.length; ++i) {
+            if (entries[i].isDirectory)
+                removeRecursivelySync(entries[i]);
+            else
+                entries[i].remove();
+        }
+    } while (entries.length);
+    if (directory.fullPath != '/')
+        directory.remove();
+}
+
 if (this.importScripts && !this.requestFileSystem) {
     debug('This test requires FileSystem API.');
     finishJSTest();
 }
-
-onmessage = function(event) {
-    importScripts(event.data);
-}
diff --git a/LayoutTests/fast/filesystem/resources/fs-worker-test-pre.js b/LayoutTests/fast/filesystem/resources/fs-worker-test-pre.js
index 84e0fad..6d9a873 100644
--- a/LayoutTests/fast/filesystem/resources/fs-worker-test-pre.js
+++ b/LayoutTests/fast/filesystem/resources/fs-worker-test-pre.js
@@ -9,8 +9,7 @@ function debug(message)
 function startWorker(testScriptURL)
 {
     debug('Starting worker: ' + testScriptURL);
-    var worker = new Worker('../resources/fs-worker-common.js');
-    worker.postMessage(testScriptURL);
+    var worker = new Worker(testScriptURL);
     worker.onmessage = function(event)
     {
         debug(event.data);
diff --git a/LayoutTests/fast/filesystem/resources/simple-persistent-sync.js b/LayoutTests/fast/filesystem/resources/simple-persistent-sync.js
index 35b0090..a7d03d2 100644
--- a/LayoutTests/fast/filesystem/resources/simple-persistent-sync.js
+++ b/LayoutTests/fast/filesystem/resources/simple-persistent-sync.js
@@ -1,3 +1,8 @@
+if (this.importScripts) {
+    importScripts('../resources/fs-worker-common.js');
+    importScripts('../resources/fs-test-util.js');
+}
+
 description("requestFileSystemSync PERSISTENT test.");
 
 var fileSystem = requestFileSystemSync(PERSISTENT, 100);
diff --git a/LayoutTests/fast/filesystem/resources/simple-persistent.js b/LayoutTests/fast/filesystem/resources/simple-persistent.js
index 369f74a..21efaf0 100644
--- a/LayoutTests/fast/filesystem/resources/simple-persistent.js
+++ b/LayoutTests/fast/filesystem/resources/simple-persistent.js
@@ -1,3 +1,8 @@
+if (this.importScripts) {
+    importScripts('../resources/fs-worker-common.js');
+    importScripts('../resources/fs-test-util.js');
+}
+
 description("requestFileSystem PERSISTENT test.");
 
 var fileSystem = null;
diff --git a/LayoutTests/fast/filesystem/resources/simple-temporary-sync.js b/LayoutTests/fast/filesystem/resources/simple-temporary-sync.js
index a33f1d9..6bf4442 100644
--- a/LayoutTests/fast/filesystem/resources/simple-temporary-sync.js
+++ b/LayoutTests/fast/filesystem/resources/simple-temporary-sync.js
@@ -1,3 +1,8 @@
+if (this.importScripts) {
+    importScripts('../resources/fs-worker-common.js');
+    importScripts('../resources/fs-test-util.js');
+}
+
 description("requestFileSystemSync TEMPORARY test.");
 
 var fileSystem = requestFileSystemSync(TEMPORARY, 100);
diff --git a/LayoutTests/fast/filesystem/resources/simple-temporary.js b/LayoutTests/fast/filesystem/resources/simple-temporary.js
index 148685c..6d57da7 100644
--- a/LayoutTests/fast/filesystem/resources/simple-temporary.js
+++ b/LayoutTests/fast/filesystem/resources/simple-temporary.js
@@ -1,3 +1,8 @@
+if (this.importScripts) {
+    importScripts('../resources/fs-worker-common.js');
+    importScripts('../resources/fs-test-util.js');
+}
+
 description("requestFileSystem TEMPORARY test.");
 
 var fileSystem = null;
diff --git a/LayoutTests/fast/filesystem/resources/sync-operations.js b/LayoutTests/fast/filesystem/resources/sync-operations.js
new file mode 100644
index 0000000..e5963d6
--- /dev/null
+++ b/LayoutTests/fast/filesystem/resources/sync-operations.js
@@ -0,0 +1,44 @@
+if (this.importScripts) {
+    importScripts('../resources/fs-worker-common.js');
+    importScripts('../resources/fs-test-util.js');
+}
+
+description("Test making multiple synchronous FileSystem operations.");
+
+var fileSystem = requestFileSystemSync(this.TEMPORARY, 100);
+removeRecursivelySync(fileSystem.root);
+
+// Stage 1 (prepare)
+var a = fileSystem.root.getFile('a', {create:true});
+var b = fileSystem.root.getDirectory('b', {create:true});
+var c = fileSystem.root.getDirectory('c', {create:true});
+var d = fileSystem.root.getFile('d', {create:true});
+
+// Stage 2 (test)
+var a_copy = a.copyTo(b, 'tmp');
+var metadata = a.getMetadata();
+var b_parent = b.getParent();
+var c_copy = c.copyTo(fileSystem.root, 'f');
+var d_new = d.moveTo(fileSystem.root, 'd2');
+var e = fileSystem.root.getFile('e', {create:true});
+
+// Verify
+var reader = fileSystem.root.createReader();
+var dirsCount = 0;
+var paths = [];
+do {
+    var entries = reader.readEntries();
+    for (var i = 0; i < entries.length; ++i) {
+        paths.push(entries[i].fullPath);
+        if (entries[i].isDirectory)
+            dirsCount++;
+    }
+} while (entries.length);
+
+paths.sort();
+shouldBe('"' + paths.join(',') + '"', '"/a,/b,/c,/d2,/e,/f"');
+shouldBe("dirsCount", "3");
+removeRecursivelySync(fileSystem.root);
+finishJSTest();
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/filesystem/script-tests/flags-passing.js b/LayoutTests/fast/filesystem/script-tests/flags-passing.js
index dbfeede..9b06427 100644
--- a/LayoutTests/fast/filesystem/script-tests/flags-passing.js
+++ b/LayoutTests/fast/filesystem/script-tests/flags-passing.js
@@ -94,8 +94,8 @@ function fileSystemCallback(fs) {
 }
 
 if (window.requestFileSystem) {
-    requestFileSystem(window.TEMPORARY, 100, fileSystemCallback, errorCallback);
     window.jsTestIsAsync = true;
+    requestFileSystem(window.TEMPORARY, 100, fileSystemCallback, errorCallback);
 } else
     debug("This test requires FileSystem API support.");
 
diff --git a/LayoutTests/fast/filesystem/workers/async-operations-expected.txt b/LayoutTests/fast/filesystem/workers/async-operations-expected.txt
new file mode 100644
index 0000000..6dbd7d7
--- /dev/null
+++ b/LayoutTests/fast/filesystem/workers/async-operations-expected.txt
@@ -0,0 +1,15 @@
+This tests running multiple async filesystem operations in Worker.
+
+Starting worker: ../resources/async-operations.js
+Description: Test making multiple async FileSystem operations.
+requested FileSystem.
+Got FileSystem:file__0:Temporary
+Starting async test stage 1.
+Starting async test stage 2.
+Verifying the FileSystem status.
+PASS: "/a,/b,/c,/d2,/e,/f" is "/a,/b,/c,/d2,/e,/f"
+PASS: dirsCount is 3
+DONE
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/filesystem/workers/async-operations.html b/LayoutTests/fast/filesystem/workers/async-operations.html
new file mode 100644
index 0000000..7a7cc4f
--- /dev/null
+++ b/LayoutTests/fast/filesystem/workers/async-operations.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<script src="../resources/fs-worker-common.js"></script>
+<script src="../resources/fs-worker-test-pre.js"></script>
+</head>
+<body>
+<p id="description">This tests running multiple async filesystem operations in Worker.</p>
+<div id="console"></div>
+<script>
+startWorker('../resources/async-operations.js');
+</script>
+<script src="../resources/fs-worker-test-post.js"></script>
+</body>
+</html>
+
diff --git a/LayoutTests/fast/filesystem/workers/simple-persistent-expected.txt b/LayoutTests/fast/filesystem/workers/simple-persistent-expected.txt
index 3fc55dd..f422433 100644
--- a/LayoutTests/fast/filesystem/workers/simple-persistent-expected.txt
+++ b/LayoutTests/fast/filesystem/workers/simple-persistent-expected.txt
@@ -2,7 +2,7 @@ This tests requesting PERSISTENT FileSystem in Worker.
 
 Starting worker: ../resources/simple-persistent.js
 Description: requestFileSystem PERSISTENT test.
-Successfully obtained PERSISTENT FileSystem:file__0:Temporary
+Successfully obtained PERSISTENT FileSystem:file__0:Persistent
 PASS: fileSystem.name.length > 0 is true
 PASS: fileSystem.root.fullPath is "/"
 DONE
diff --git a/LayoutTests/fast/filesystem/workers/simple-persistent-sync-expected.txt b/LayoutTests/fast/filesystem/workers/simple-persistent-sync-expected.txt
index 23ebfbd..06ab5f5 100644
--- a/LayoutTests/fast/filesystem/workers/simple-persistent-sync-expected.txt
+++ b/LayoutTests/fast/filesystem/workers/simple-persistent-sync-expected.txt
@@ -2,7 +2,10 @@ This tests requesting PERSISTENT FileSystemSync in Worker.
 
 Starting worker: ../resources/simple-persistent-sync.js
 Description: requestFileSystemSync PERSISTENT test.
-Got error from worker: Uncaught ReferenceError: requestFileSystemSync is not defined
+Successfully obtained PERSISTENT FileSystem:file__0:Persistent
+PASS: fileSystem.name.length > 0 is true
+PASS: fileSystem.root.fullPath is "/"
+DONE
 
 TEST COMPLETE
 
diff --git a/LayoutTests/fast/filesystem/workers/simple-persistent-sync.txt b/LayoutTests/fast/filesystem/workers/simple-persistent-sync.txt
deleted file mode 100644
index 19ed6c5..0000000
--- a/LayoutTests/fast/filesystem/workers/simple-persistent-sync.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This tests requesting PERSISTENT FileSystemSync in Worker.
-
-Starting worker: ../resources/simple-persistent-sync.js
-Worker started.
-Successfully obtained PERSISTENT FileSystem:http_localhost_8080:Persistent
-PASS: fileSystem.name.length > 0 is true
-PASS: fileSystem.root.fullPath is "/"
-DONE
-
-TEST COMPLETE
-
-
diff --git a/LayoutTests/fast/filesystem/workers/simple-temporary-sync-expected.txt b/LayoutTests/fast/filesystem/workers/simple-temporary-sync-expected.txt
index 0e21c02..28be090 100644
--- a/LayoutTests/fast/filesystem/workers/simple-temporary-sync-expected.txt
+++ b/LayoutTests/fast/filesystem/workers/simple-temporary-sync-expected.txt
@@ -2,7 +2,10 @@ This tests requesting TEMPORARY FileSystemSync in Worker.
 
 Starting worker: ../resources/simple-temporary-sync.js
 Description: requestFileSystemSync TEMPORARY test.
-Got error from worker: Uncaught ReferenceError: requestFileSystemSync is not defined
+Successfully obtained TEMPORARY FileSystem:file__0:Temporary
+PASS: fileSystem.name.length > 0 is true
+PASS: fileSystem.root.fullPath is "/"
+DONE
 
 TEST COMPLETE
 
diff --git a/LayoutTests/fast/filesystem/workers/sync-operations-expected.txt b/LayoutTests/fast/filesystem/workers/sync-operations-expected.txt
new file mode 100644
index 0000000..13855d5
--- /dev/null
+++ b/LayoutTests/fast/filesystem/workers/sync-operations-expected.txt
@@ -0,0 +1,10 @@
+This tests running multiple sync filesystem operations in Worker.
+
+Starting worker: ../resources/sync-operations.js
+Description: Test making multiple synchronous FileSystem operations.
+PASS: "/a,/b,/c,/d2,/e,/f" is "/a,/b,/c,/d2,/e,/f"
+PASS: dirsCount is 3
+DONE
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/filesystem/workers/sync-operations.html b/LayoutTests/fast/filesystem/workers/sync-operations.html
new file mode 100644
index 0000000..92adf04
--- /dev/null
+++ b/LayoutTests/fast/filesystem/workers/sync-operations.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<script src="../resources/fs-worker-common.js"></script>
+<script src="../resources/fs-worker-test-pre.js"></script>
+</head>
+<body>
+<p id="description">This tests running multiple sync filesystem operations in Worker.</p>
+<div id="console"></div>
+<script>
+startWorker('../resources/sync-operations.js');
+</script>
+<script src="../resources/fs-worker-test-post.js"></script>
+</body>
+</html>
+
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index bbcf576..6b09251 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -925,154 +925,6 @@
         (WebCore::SVGFilter::sourceImageRect):
         (WebCore::SVGFilter::maxImageSize):
 
-2010-10-06  Pavel Podivilov  <podivilov at chromium.org>
-
-        Reviewed by Yury Semikhatsky.
-
-        Web Inspector: add "Set Breakpoint" item to XHR resource context menu.
-        https://bugs.webkit.org/show_bug.cgi?id=47085
-
-        * English.lproj/localizedStrings.js:
-        * inspector/front-end/ResourcesPanel.js:
-        (WebInspector.ResourcesPanel.prototype._contextMenu):
-
-2010-10-05  Kinuko Yasuda  <kinuko at chromium.org>
-
-        Reviewed by David Levin.
-
-        Add idl and mock classes for FileSystemSync for FileSystem API
-        https://bugs.webkit.org/show_bug.cgi?id=46405
-
-        Added bunch of *Sync classes, plus refactored some classes:
-        Added DOMFileSystemBase as a common base class for DOMFileSystem and
-        DOMFileSystemSync.
-        Added EntryBase as a common base class for Entry and EntrySync.
-        Added DirectoryReaderBase as a common base class for DirectoryReader and
-        DirectoryReaderSync.
-
-        Test: fast/filesystem/workers/
-
-        * CMakeLists.txt: Added new files.
-        * DerivedSources.cpp: Added new files.
-        * DerivedSources.make: Added new files.
-        * GNUmakefile.am: Added new files.
-        * WebCore.gypi: Added new files.
-        * WebCore.pri: Added new files.
-        * WebCore.pro: Added new files.
-        * WebCore.vcproj/WebCore.vcproj: Added new files. Also removed the duplicated fileapi\FileEntry.cpp entry.
-        * WebCore.xcodeproj/project.pbxproj: Added new files.
-        * bindings/js/JSDirectoryEntrySyncCustom.cpp: Added.
-        * bindings/js/JSEntrySyncCustom.cpp: Added.
-        * bindings/v8/custom/V8DirectoryEntrySyncCustom.cpp: Added.
-        * bindings/v8/custom/V8EntrySyncCustom.cpp: Added.
-        * fileapi/DOMFileSystemBase.cpp: Added.
-        * fileapi/DOMFileSystemBase.h: Added.
-        * fileapi/DOMFileSystemSync.cpp: Added.
-        * fileapi/DOMFileSystemSync.h: Added.
-        * fileapi/DOMFileSystemSync.idl: Added.
-        * fileapi/DirectoryEntrySync.cpp: Added.
-        * fileapi/DirectoryEntrySync.h: Added.
-        * fileapi/DirectoryEntrySync.idl: Added.
-        * fileapi/DirectoryReaderBase.h: Added.
-        * fileapi/DirectoryReaderSync.cpp: Added.
-        * fileapi/DirectoryReaderSync.h: Added.
-        * fileapi/DirectoryReaderSync.idl: Added.
-        * fileapi/EntryArraySync.cpp: Added.
-        * fileapi/EntryArraySync.h: Added.
-        * fileapi/EntryArraySync.idl: Added.
-        * fileapi/EntryBase.h: Added.
-        * fileapi/EntrySync.cpp: Added.
-        * fileapi/EntrySync.h: Added.
-        * fileapi/EntrySync.idl: Added.
-        * fileapi/FileEntrySync.cpp: Added.
-        * fileapi/FileEntrySync.h: Added.
-        * fileapi/FileEntrySync.idl: Added.
-
-2010-10-05  Kent Tamura  <tkent at chromium.org>
-
-        Reviewed by Dimitri Glazkov.
-
-        REGRESSION (r67166): "Placeholder" text remains in input box after 2nd focus()
-        https://bugs.webkit.org/show_bug.cgi?id=45940
-
-        Test: fast/forms/input-placeholder-focus-twice.html
-
-        * html/HTMLFormControlElement.h: Make supportsPlaceholder() public.
-        * rendering/RenderTextControlSingleLine.cpp:
-        (WebCore::RenderTextControlSingleLine::updateFromElement):
-         We always need to update the renderer value with the DOM value if
-         the element supports the placeholder feature.
-         Note: the placeholder feature and "unacceptable renderer value"
-         are exclusive.
-
-2010-10-05  Kyusun Kim  <maniagoon at company100.net>
-
-        Reviewed by Kent Tamura.
-
-        [BREWMP] Translate key code in PlatformKeyboardEvent with IKeysMapping
-        https://bugs.webkit.org/show_bug.cgi?id=47234
-
-        Brew MP devices have a variey of key configurations and use modifiers to
-        input capital letters, symbols and special characters. Use IKeysMapping to translate key code.
-
-        * platform/brew/PlatformKeyboardEventBrew.cpp:
-        (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
-
-2010-10-05  W. James MacLean  <wjmaclean at chromium.org>
-
-        Reviewed by James Robinson.
-
-        [chromium] Add mipmap support for ImageLayerChromium
-        https://bugs.webkit.org/show_bug.cgi?id=46493
-
-        Mipmap behaviour can be tested with existing tests.
-        Tests in LayoutTests/compositing/images/ will detect if
-        mipmaps fail.
-
-        * platform/graphics/chromium/ContentLayerChromium.cpp:
-        (WebCore::ContentLayerChromium::SharedValues::SharedValues):
-        (WebCore::isPowerOfTwo):
-        (WebCore::ContentLayerChromium::updateTextureRect):
-        * platform/graphics/chromium/ContentLayerChromium.h:
-        (WebCore::ContentLayerChromium::SharedValues::npotSupported):
-        * platform/graphics/chromium/ImageLayerChromium.cpp:
-        (WebCore::ImageLayerChromium::updateContents):
-
-2010-10-05  Adam Barth  <abarth at webkit.org>
-
-        Reviewed by Darin Adler.
-
-        Issue in treebuilder parsing related to table tags
-        https://bugs.webkit.org/show_bug.cgi?id=47190
-
-        Update ASSERT to match the spec and our behavior.
-
-        * html/parser/HTMLTreeBuilder.cpp:
-        (WebCore::HTMLTreeBuilder::processEndTagForInCell):
-
-2010-10-05  Victoria Kirst  <vrk at google.com>
-
-        Reviewed by James Robinson.
-
-        VideoLayerChromium releases old resources if the LayerRenderer changes.
-        https://bugs.webkit.org/show_bug.cgi?id=47030
-
-        Refactored LayerChromium to have a virtual cleanupResources() method
-        that will release textures/other context-dependent resources when a
-        LayerRenderer changes. ContentLayerChromium and VideoLayerChromium now
-        override this method to perform cleanup.
-
-        * platform/graphics/chromium/ContentLayerChromium.cpp:
-        * platform/graphics/chromium/ContentLayerChromium.h:
-        * platform/graphics/chromium/LayerChromium.cpp:
-        (WebCore::LayerChromium::setLayerRenderer):
-        * platform/graphics/chromium/LayerChromium.h:
-        (WebCore::LayerChromium::cleanupResources):
-        * platform/graphics/chromium/VideoLayerChromium.cpp:
-        (WebCore::VideoLayerChromium::~VideoLayerChromium):
-        (WebCore::VideoLayerChromium::cleanupResources):
-        * platform/graphics/chromium/VideoLayerChromium.h:
-
 2010-10-05  Kinuko Yasuda  <kinuko at chromium.org>
 
         Reviewed by Jian Li.
@@ -1085,63 +937,6 @@
         * fileapi/FileEntry.cpp:
         (WebCore::FileEntry::file): Implemented.
 
-2010-09-29  Alpha Lam  <hclam at chromium.org>
-
-        Reviewed by James Robinson.
-
-        Render textures in video frame directly.
-        https://bugs.webkit.org/show_bug.cgi?id=46765
-
-        Render textures in VideoLayerChromium directly if the video frame type
-        is GL texture. In the future VideoLayerChromium will not allocate
-        textures and perform textures upload as those operations will be done
-        in Chromium to minimize memory copy. This patch will help moving toward
-        this direction and facilitate hardware video decoding.
-
-        * platform/graphics/chromium/VideoFrameChromium.h:
-        * platform/graphics/chromium/VideoFrameProvider.h:
-        (WebCore::VideoFrameProvider::~VideoFrameProvider):
-        * platform/graphics/chromium/VideoLayerChromium.cpp:
-        (WebCore::VideoLayerChromium::VideoLayerChromium):
-        (WebCore::VideoLayerChromium::~VideoLayerChromium):
-        (WebCore::VideoLayerChromium::updateContents):
-        (WebCore::VideoLayerChromium::draw):
-        (WebCore::VideoLayerChromium::releaseCurrentFrame):
-        (WebCore::VideoLayerChromium::resetFrameParameters):
-        (WebCore::VideoLayerChromium::saveCurrentFrame):
-        * platform/graphics/chromium/VideoLayerChromium.h:
-        (WebCore::VideoLayerChromium::SharedValues::initialized):
-
-2010-10-05  Fady Samuel  <fsamuel at chromium.org>
-
-        Reviewed by Darin Adler.
-
-        REGRESSION (r65539): One pixel white gaps when scrolling Trac changeset pages
-        https://bugs.webkit.org/show_bug.cgi?id=45131
-
-        When border-collapse: separate property is set on the table, paintObject
-        may skip repainting cells, if the dirty region only touches one row/col of pixels.
-
-        Test: fast/table/simple_paint_separate_borders.html
-
-        * rendering/RenderTableSection.cpp:
-        (WebCore::RenderTableSection::paintObject):  
-            Don't subtract one from the right and bottom of the dirty paint rect.
-
-2010-10-05  Sanjeev Radhakrishnan  <sanjeevr at chromium.org>
-
-        Reviewed by Darin Fisher.
-
-        PluginDocument now holds on to the created plugin node so that the pluginNode() and pluginWidget() methods can return the correct node.
-        https://bugs.webkit.org/show_bug.cgi?id=47129
-
-        * html/PluginDocument.cpp:
-        (WebCore::PluginDocumentParser::createDocumentStructure):
-        (WebCore::PluginDocument::pluginWidget):
-        (WebCore::PluginDocument::pluginNode):
-        * html/PluginDocument.h:
-        (WebCore::PluginDocument::setPluginNode):
-
 2010-10-05  Andreas Kling  <kling at webkit.org>
 
         Reviewed by Tor Arne Vestbø.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index e8b2cfb..b23e5e0 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -1520,6 +1520,7 @@
             'fileapi/LocalFileSystem.h',
             'fileapi/Metadata.h',
             'fileapi/MetadataCallback.h',
+            'fileapi/SyncCallbackHelper.h',
             'fileapi/ThreadableBlobRegistry.cpp',
             'fileapi/ThreadableBlobRegistry.h',
             'history/mac/HistoryItemMac.mm',
diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
index be18366..f73b922 100644
--- a/WebCore/bindings/generic/RuntimeEnabledFeatures.h
+++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
@@ -150,7 +150,6 @@ public:
 #if ENABLE(FILE_SYSTEM)
     static bool fileSystemEnabled();
     static void setFileSystemEnabled(bool isEnabled) { isFileSystemEnabled = isEnabled; }
-    static bool requestFileSystemEnabled() { return isFileSystemEnabled; }
 #endif
 
 private:
diff --git a/WebCore/fileapi/DOMFileSystem.cpp b/WebCore/fileapi/DOMFileSystem.cpp
index 1742842..b2df13b 100644
--- a/WebCore/fileapi/DOMFileSystem.cpp
+++ b/WebCore/fileapi/DOMFileSystem.cpp
@@ -36,19 +36,13 @@
 #include "AsyncFileSystem.h"
 #include "DOMFilePath.h"
 #include "DirectoryEntry.h"
-#include "EntriesCallback.h"
-#include "Entry.h"
-#include "EntryArray.h"
-#include "EntryCallback.h"
 #include "ErrorCallback.h"
 #include "FileEntry.h"
-#include "FileError.h"
 #include "FileSystemCallbacks.h"
 #include "FileWriter.h"
 #include "FileWriterCallback.h"
 #include "MetadataCallback.h"
 #include "ScriptExecutionContext.h"
-#include "VoidCallback.h"
 #include <wtf/OwnPtr.h>
 
 namespace WebCore {
@@ -80,124 +74,6 @@ void DOMFileSystem::contextDestroyed()
     ActiveDOMObject::contextDestroyed();
 }
 
-void DOMFileSystem::getMetadata(const Entry* entry, PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    String platformPath = m_asyncFileSystem->virtualToPlatformPath(entry->fullPath());
-    m_asyncFileSystem->readMetadata(platformPath, MetadataCallbacks::create(successCallback, errorCallback));
-}
-
-static bool checkValidityForForCopyOrMove(const Entry* src, Entry* parent, const String& newName)
-{
-    ASSERT(src);
-
-    if (!parent || !parent->isDirectory())
-        return false;
-
-    if (!newName.isEmpty() && !DOMFilePath::isValidName(newName))
-        return false;
-
-    // It is an error to try to copy or move an entry inside itself at any depth if it is a directory.
-    if (src->isDirectory() && DOMFilePath::isParentOf(src->fullPath(), parent->fullPath()))
-        return false;
-
-    // It is an error to copy or move an entry into its parent if a name different from its current one isn't provided.
-    if ((newName.isEmpty() || src->name() == newName) && DOMFilePath::getDirectory(src->fullPath()) == parent->fullPath())
-        return false;
-
-    return true;
-}
-
-void DOMFileSystem::move(const Entry* src, PassRefPtr<Entry> parent, const String& newName, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    if (!checkValidityForForCopyOrMove(src, parent.get(), newName)) {
-        scheduleCallback(scriptExecutionContext(), errorCallback, FileError::create(INVALID_MODIFICATION_ERR));
-        return;
-    }
-
-    String destPath = parent->fullPath();
-    if (!newName.isEmpty())
-        destPath = DOMFilePath::append(destPath, newName);
-    else
-        destPath = DOMFilePath::append(destPath, src->name());
-
-    String srcPlatformPath = m_asyncFileSystem->virtualToPlatformPath(src->fullPath());
-    String destPlatformPath = parent->filesystem()->asyncFileSystem()->virtualToPlatformPath(destPath);
-    m_asyncFileSystem->move(srcPlatformPath, destPlatformPath, EntryCallbacks::create(successCallback, errorCallback, this, destPath, src->isDirectory()));
-}
-
-void DOMFileSystem::copy(const Entry* src, PassRefPtr<Entry> parent, const String& newName, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    if (!checkValidityForForCopyOrMove(src, parent.get(), newName)) {
-        scheduleCallback(scriptExecutionContext(), errorCallback, FileError::create(INVALID_MODIFICATION_ERR));
-        return;
-    }
-
-    String destPath = parent->fullPath();
-    if (!newName.isEmpty())
-        destPath = DOMFilePath::append(destPath, newName);
-    else
-        destPath = DOMFilePath::append(destPath, src->name());
-
-    String srcPlatformPath = m_asyncFileSystem->virtualToPlatformPath(src->fullPath());
-    String destPlatformPath = parent->filesystem()->asyncFileSystem()->virtualToPlatformPath(destPath);
-    m_asyncFileSystem->copy(srcPlatformPath, destPlatformPath, EntryCallbacks::create(successCallback, errorCallback, this, destPath, src->isDirectory()));
-}
-
-void DOMFileSystem::remove(const Entry* entry, PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    ASSERT(entry);
-    String platformPath = m_asyncFileSystem->virtualToPlatformPath(entry->fullPath());
-    m_asyncFileSystem->remove(platformPath, VoidCallbacks::create(successCallback, errorCallback));
-}
-
-void DOMFileSystem::getParent(const Entry* entry, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    ASSERT(entry);
-    String path = DOMFilePath::getDirectory(entry->fullPath());
-    String platformPath = m_asyncFileSystem->virtualToPlatformPath(path);
-    m_asyncFileSystem->directoryExists(platformPath, EntryCallbacks::create(successCallback, errorCallback, this, path, true));
-}
-
-void DOMFileSystem::getFile(const Entry* base, const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    ASSERT(base);
-    if (!DOMFilePath::isValidPath(path)) {
-        scheduleCallback(scriptExecutionContext(), errorCallback, FileError::create(INVALID_MODIFICATION_ERR));
-        return;
-    }
-
-    String absolutePath = path;
-    if (!DOMFilePath::isAbsolute(path))
-        absolutePath = DOMFilePath::removeExtraParentReferences(DOMFilePath::append(base->fullPath(), path));
-    String platformPath = m_asyncFileSystem->virtualToPlatformPath(absolutePath);
-
-    OwnPtr<EntryCallbacks> callbacks = EntryCallbacks::create(successCallback, errorCallback, this, absolutePath, false);
-    if (flags && flags->isCreate())
-        m_asyncFileSystem->createFile(platformPath, flags->isExclusive(), callbacks.release());
-    else
-        m_asyncFileSystem->fileExists(platformPath, callbacks.release());
-}
-
-void DOMFileSystem::getDirectory(const Entry* base, const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    ASSERT(base);
-    if (!DOMFilePath::isValidPath(path)) {
-        scheduleCallback(scriptExecutionContext(), errorCallback, FileError::create(INVALID_MODIFICATION_ERR));
-        return;
-    }
-
-    String absolutePath = path;
-    if (!DOMFilePath::isAbsolute(path))
-        absolutePath = DOMFilePath::removeExtraParentReferences(DOMFilePath::append(base->fullPath(), path));
-    String platformPath = m_asyncFileSystem->virtualToPlatformPath(absolutePath);
-
-    OwnPtr<EntryCallbacks> callbacks = EntryCallbacks::create(successCallback, errorCallback, this, absolutePath, true);
-    if (flags && flags->isCreate())
-        m_asyncFileSystem->createDirectory(platformPath, flags->isExclusive(), callbacks.release());
-    else
-        m_asyncFileSystem->directoryExists(platformPath, callbacks.release());
-}
-
 void DOMFileSystem::createWriter(const FileEntry* file, PassRefPtr<FileWriterCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
 {
     ASSERT(file);
@@ -209,13 +85,6 @@ void DOMFileSystem::createWriter(const FileEntry* file, PassRefPtr<FileWriterCal
     m_asyncFileSystem->createWriter(fileWriter.get(), platformPath, callbacks.release());
 }
 
-void DOMFileSystem::readDirectory(DirectoryReader* reader, const String& path, PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
-{
-    ASSERT(DOMFilePath::isAbsolute(path));
-    String platformPath = m_asyncFileSystem->virtualToPlatformPath(path);
-    m_asyncFileSystem->readDirectory(platformPath, EntriesCallbacks::create(successCallback, errorCallback, reader, path));
-}
-
 } // namespace
 
 #endif // ENABLE(FILE_SYSTEM)
diff --git a/WebCore/fileapi/DOMFileSystem.h b/WebCore/fileapi/DOMFileSystem.h
index 908c16c..5f44afa 100644
--- a/WebCore/fileapi/DOMFileSystem.h
+++ b/WebCore/fileapi/DOMFileSystem.h
@@ -34,26 +34,14 @@
 #if ENABLE(FILE_SYSTEM)
 
 #include "ActiveDOMObject.h"
-#include "AsyncFileSystem.h"
 #include "DOMFileSystemBase.h"
-#include "Flags.h"
-#include "PlatformString.h"
 #include "ScriptExecutionContext.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
 
 namespace WebCore {
 
 class DirectoryEntry;
-class DirectoryReader;
-class Entry;
-class EntryCallback;
-class EntriesCallback;
-class ErrorCallback;
 class FileEntry;
 class FileWriterCallback;
-class MetadataCallback;
-class VoidCallback;
 
 class DOMFileSystem : public DOMFileSystemBase, public ActiveDOMObject {
 public:
@@ -69,15 +57,6 @@ public:
     virtual bool hasPendingActivity() const;
     virtual void contextDestroyed();
 
-    // Actual FileSystem API implementations.  All the validity checks on virtual paths are done at DOMFileSystem level.
-    void getMetadata(const Entry* entry, PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback);
-    void move(const Entry* src, PassRefPtr<Entry> parent, const String& name, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
-    void copy(const Entry* src, PassRefPtr<Entry> parent, const String& name, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
-    void remove(const Entry* entry, PassRefPtr<VoidCallback>, PassRefPtr<ErrorCallback>);
-    void getParent(const Entry* entry, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
-    void getFile(const Entry* base, const String& path, PassRefPtr<Flags>, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
-    void getDirectory(const Entry* base, const String& path, PassRefPtr<Flags>, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
-    void readDirectory(DirectoryReader* reader, const String& path, PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>);
     void createWriter(const FileEntry* file, PassRefPtr<FileWriterCallback>, PassRefPtr<ErrorCallback>);
 
     // Schedule a callback. This should not cross threads (should be called on the same context thread).
@@ -95,7 +74,6 @@ private:
     DOMFileSystem(ScriptExecutionContext*, const String& name, PassOwnPtr<AsyncFileSystem>);
 
     // A helper template to schedule a callback task.
-    // FIXME: move this to a more generic place.
     template <typename CB, typename CBArg>
     class DispatchCallbackTask : public ScriptExecutionContext::Task {
     public:
@@ -120,6 +98,7 @@ template <typename CB, typename CBArg>
 void DOMFileSystem::scheduleCallback(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<CB> callback, PassRefPtr<CBArg> arg)
 {
     ASSERT(scriptExecutionContext->isContextThread());
+    ASSERT(callback);
     scriptExecutionContext->postTask(new DispatchCallbackTask<CB, CBArg>(callback, arg));
 }
 
diff --git a/WebCore/fileapi/DOMFileSystemBase.cpp b/WebCore/fileapi/DOMFileSystemBase.cpp
index b69882d..63c6e5b 100644
--- a/WebCore/fileapi/DOMFileSystemBase.cpp
+++ b/WebCore/fileapi/DOMFileSystemBase.cpp
@@ -34,6 +34,16 @@
 #if ENABLE(FILE_SYSTEM)
 
 #include "DOMFilePath.h"
+#include "DirectoryEntry.h"
+#include "EntriesCallback.h"
+#include "EntryArray.h"
+#include "EntryBase.h"
+#include "EntryCallback.h"
+#include "ErrorCallback.h"
+#include "FileError.h"
+#include "FileSystemCallbacks.h"
+#include "MetadataCallback.h"
+#include "VoidCallback.h"
 #include <wtf/OwnPtr.h>
 
 namespace WebCore {
@@ -48,6 +58,131 @@ DOMFileSystemBase::~DOMFileSystemBase()
 {
 }
 
+bool DOMFileSystemBase::getMetadata(const EntryBase* entry, PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    String platformPath = m_asyncFileSystem->virtualToPlatformPath(entry->fullPath());
+    m_asyncFileSystem->readMetadata(platformPath, MetadataCallbacks::create(successCallback, errorCallback));
+    return true;
+}
+
+static bool checkValidityForForCopyOrMove(const EntryBase* source, EntryBase* parent, const String& newName)
+{
+    ASSERT(source);
+
+    if (!parent || !parent->isDirectory())
+        return false;
+
+    if (!newName.isEmpty() && !DOMFilePath::isValidName(newName))
+        return false;
+
+    // It is an error to try to copy or move an entry inside itself at any depth if it is a directory.
+    if (source->isDirectory() && DOMFilePath::isParentOf(source->fullPath(), parent->fullPath()))
+        return false;
+
+    // It is an error to copy or move an entry into its parent if a name different from its current one isn't provided.
+    if ((newName.isEmpty() || source->name() == newName) && DOMFilePath::getDirectory(source->fullPath()) == parent->fullPath())
+        return false;
+
+    return true;
+}
+
+bool DOMFileSystemBase::move(const EntryBase* source, EntryBase* parent, const String& newName, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    if (!checkValidityForForCopyOrMove(source, parent, newName))
+        return false;
+
+    String destinationPath = parent->fullPath();
+    if (!newName.isEmpty())
+        destinationPath = DOMFilePath::append(destinationPath, newName);
+    else
+        destinationPath = DOMFilePath::append(destinationPath, source->name());
+
+    String sourcePlatformPath = m_asyncFileSystem->virtualToPlatformPath(source->fullPath());
+    String destinationPlatformPath = parent->filesystem()->asyncFileSystem()->virtualToPlatformPath(destinationPath);
+    m_asyncFileSystem->move(sourcePlatformPath, destinationPlatformPath, EntryCallbacks::create(successCallback, errorCallback, this, destinationPath, source->isDirectory()));
+    return true;
+}
+
+bool DOMFileSystemBase::copy(const EntryBase* source, EntryBase* parent, const String& newName, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    if (!checkValidityForForCopyOrMove(source, parent, newName))
+        return false;
+
+    String destinationPath = parent->fullPath();
+    if (!newName.isEmpty())
+        destinationPath = DOMFilePath::append(destinationPath, newName);
+    else
+        destinationPath = DOMFilePath::append(destinationPath, source->name());
+
+    String sourcePlatformPath = m_asyncFileSystem->virtualToPlatformPath(source->fullPath());
+    String destinationPlatformPath = parent->filesystem()->asyncFileSystem()->virtualToPlatformPath(destinationPath);
+    m_asyncFileSystem->copy(sourcePlatformPath, destinationPlatformPath, EntryCallbacks::create(successCallback, errorCallback, this, destinationPath, source->isDirectory()));
+    return true;
+}
+
+bool DOMFileSystemBase::remove(const EntryBase* entry, PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    ASSERT(entry);
+    String platformPath = m_asyncFileSystem->virtualToPlatformPath(entry->fullPath());
+    m_asyncFileSystem->remove(platformPath, VoidCallbacks::create(successCallback, errorCallback));
+    return true;
+}
+
+bool DOMFileSystemBase::getParent(const EntryBase* entry, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    ASSERT(entry);
+    String path = DOMFilePath::getDirectory(entry->fullPath());
+    String platformPath = m_asyncFileSystem->virtualToPlatformPath(path);
+    m_asyncFileSystem->directoryExists(platformPath, EntryCallbacks::create(successCallback, errorCallback, this, path, true));
+    return true;
+}
+
+bool DOMFileSystemBase::getFile(const EntryBase* base, const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    ASSERT(base);
+    if (!DOMFilePath::isValidPath(path))
+        return false;
+
+    String absolutePath = path;
+    if (!DOMFilePath::isAbsolute(path))
+        absolutePath = DOMFilePath::removeExtraParentReferences(DOMFilePath::append(base->fullPath(), path));
+    String platformPath = m_asyncFileSystem->virtualToPlatformPath(absolutePath);
+
+    OwnPtr<EntryCallbacks> callbacks = EntryCallbacks::create(successCallback, errorCallback, this, absolutePath, false);
+    if (flags && flags->isCreate())
+        m_asyncFileSystem->createFile(platformPath, flags->isExclusive(), callbacks.release());
+    else
+        m_asyncFileSystem->fileExists(platformPath, callbacks.release());
+    return true;
+}
+
+bool DOMFileSystemBase::getDirectory(const EntryBase* base, const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    ASSERT(base);
+    if (!DOMFilePath::isValidPath(path))
+        return false;
+
+    String absolutePath = path;
+    if (!DOMFilePath::isAbsolute(path))
+        absolutePath = DOMFilePath::removeExtraParentReferences(DOMFilePath::append(base->fullPath(), path));
+    String platformPath = m_asyncFileSystem->virtualToPlatformPath(absolutePath);
+
+    OwnPtr<EntryCallbacks> callbacks = EntryCallbacks::create(successCallback, errorCallback, this, absolutePath, true);
+    if (flags && flags->isCreate())
+        m_asyncFileSystem->createDirectory(platformPath, flags->isExclusive(), callbacks.release());
+    else
+        m_asyncFileSystem->directoryExists(platformPath, callbacks.release());
+    return true;
+}
+
+bool DOMFileSystemBase::readDirectory(DirectoryReaderBase* reader, const String& path, PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+{
+    ASSERT(DOMFilePath::isAbsolute(path));
+    String platformPath = m_asyncFileSystem->virtualToPlatformPath(path);
+    m_asyncFileSystem->readDirectory(platformPath, EntriesCallbacks::create(successCallback, errorCallback, reader, path));
+    return true;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(FILE_SYSTEM)
diff --git a/WebCore/fileapi/DOMFileSystemBase.h b/WebCore/fileapi/DOMFileSystemBase.h
index e714d8d..ee8f8e5 100644
--- a/WebCore/fileapi/DOMFileSystemBase.h
+++ b/WebCore/fileapi/DOMFileSystemBase.h
@@ -34,12 +34,22 @@
 #if ENABLE(FILE_SYSTEM)
 
 #include "AsyncFileSystem.h"
+#include "Flags.h"
 #include "PlatformString.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
 
+class DirectoryEntry;
+class DirectoryReaderBase;
+class EntriesCallback;
+class EntryBase;
+class EntryCallback;
+class ErrorCallback;
+class MetadataCallback;
+class VoidCallback;
+
 // A common base class for DOMFileSystem and DOMFileSystemSync.
 class DOMFileSystemBase : public RefCounted<DOMFileSystemBase> {
 public:
@@ -52,6 +62,17 @@ public:
     const String& name() const { return m_name; }
     AsyncFileSystem* asyncFileSystem() const { return m_asyncFileSystem.get(); }
 
+    // Actual FileSystem API implementations.  All the validity checks on virtual paths are done at this level.
+    // They return false for immediate errors that don't involve lower AsyncFileSystem layer (e.g. for name validation errors).  Otherwise they return true (but later may call back with an runtime error).
+    bool getMetadata(const EntryBase*, PassRefPtr<MetadataCallback>, PassRefPtr<ErrorCallback>);
+    bool move(const EntryBase* source, EntryBase* parent, const String& name, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
+    bool copy(const EntryBase* source, EntryBase* parent, const String& name, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
+    bool remove(const EntryBase*, PassRefPtr<VoidCallback>, PassRefPtr<ErrorCallback>);
+    bool getParent(const EntryBase*, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
+    bool getFile(const EntryBase*, const String& path, PassRefPtr<Flags>, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
+    bool getDirectory(const EntryBase*, const String& path, PassRefPtr<Flags>, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
+    bool readDirectory(DirectoryReaderBase*, const String& path, PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>);
+
 protected:
     DOMFileSystemBase(const String& name, PassOwnPtr<AsyncFileSystem>);
     friend class DOMFileSystemSync;
diff --git a/WebCore/fileapi/DOMFileSystemSync.cpp b/WebCore/fileapi/DOMFileSystemSync.cpp
index e200d22..96c76fe 100644
--- a/WebCore/fileapi/DOMFileSystemSync.cpp
+++ b/WebCore/fileapi/DOMFileSystemSync.cpp
@@ -38,6 +38,11 @@
 
 namespace WebCore {
 
+PassRefPtr<DOMFileSystemSync> DOMFileSystemSync::create(DOMFileSystemBase* fileSystem)
+{
+    return adoptRef(new DOMFileSystemSync(fileSystem->m_name, fileSystem->m_asyncFileSystem.release()));
+}
+
 DOMFileSystemSync::DOMFileSystemSync(const String& name, PassOwnPtr<AsyncFileSystem> asyncFileSystem)
     : DOMFileSystemBase(name, asyncFileSystem)
 {
diff --git a/WebCore/fileapi/DOMFileSystemSync.h b/WebCore/fileapi/DOMFileSystemSync.h
index 6e64526..9aeafc8 100644
--- a/WebCore/fileapi/DOMFileSystemSync.h
+++ b/WebCore/fileapi/DOMFileSystemSync.h
@@ -48,6 +48,8 @@ public:
         return adoptRef(new DOMFileSystemSync(name, asyncFileSystem));
     }
 
+    static PassRefPtr<DOMFileSystemSync> create(DOMFileSystemBase*);
+
     virtual ~DOMFileSystemSync();
 
     PassRefPtr<DirectoryEntrySync> root();
diff --git a/WebCore/fileapi/DirectoryEntry.cpp b/WebCore/fileapi/DirectoryEntry.cpp
index f78787a..ebeb95a 100644
--- a/WebCore/fileapi/DirectoryEntry.cpp
+++ b/WebCore/fileapi/DirectoryEntry.cpp
@@ -36,10 +36,11 @@
 #include "DirectoryReader.h"
 #include "EntryCallback.h"
 #include "ErrorCallback.h"
+#include "FileError.h"
 
 namespace WebCore {
 
-DirectoryEntry::DirectoryEntry(DOMFileSystem* fileSystem, const String& fullPath)
+DirectoryEntry::DirectoryEntry(DOMFileSystemBase* fileSystem, const String& fullPath)
     : Entry(fileSystem, fullPath)
 {
 }
@@ -49,16 +50,20 @@ PassRefPtr<DirectoryReader> DirectoryEntry::createReader()
     return DirectoryReader::create(m_fileSystem, m_fullPath);
 }
 
-void DirectoryEntry::getFile(const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+void DirectoryEntry::getFile(const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef)
 {
-    filesystem()->getFile(this, path, flags, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->getFile(this, path, flags, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
-void DirectoryEntry::getDirectory(const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+void DirectoryEntry::getDirectory(const String& path, PassRefPtr<Flags> flags, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef)
 {
-    filesystem()->getDirectory(this, path, flags, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->getDirectory(this, path, flags, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
-} // namespace
+}
 
 #endif // ENABLE(FILE_SYSTEM)
diff --git a/WebCore/fileapi/DirectoryEntry.h b/WebCore/fileapi/DirectoryEntry.h
index c76b204..69a52ab 100644
--- a/WebCore/fileapi/DirectoryEntry.h
+++ b/WebCore/fileapi/DirectoryEntry.h
@@ -41,13 +41,14 @@
 
 namespace WebCore {
 
+class DOMFileSystemBase;
 class DirectoryReader;
 class EntryCallback;
 class ErrorCallback;
 
 class DirectoryEntry : public Entry {
 public:
-    static PassRefPtr<DirectoryEntry> create(DOMFileSystem* fileSystem, const String& fullPath)
+    static PassRefPtr<DirectoryEntry> create(DOMFileSystemBase* fileSystem, const String& fullPath)
     {
         return adoptRef(new DirectoryEntry(fileSystem, fullPath));
     }
@@ -58,7 +59,7 @@ public:
     void getDirectory(const String& path, PassRefPtr<Flags> = 0, PassRefPtr<EntryCallback> = 0, PassRefPtr<ErrorCallback> = 0);
 
 private:
-    DirectoryEntry(DOMFileSystem* fileSystem, const String& fullPath);
+    DirectoryEntry(DOMFileSystemBase*, const String& fullPath);
 };
 
 } // namespace
diff --git a/WebCore/fileapi/DirectoryEntrySync.cpp b/WebCore/fileapi/DirectoryEntrySync.cpp
index 1ad2cf5..b228db5 100644
--- a/WebCore/fileapi/DirectoryEntrySync.cpp
+++ b/WebCore/fileapi/DirectoryEntrySync.cpp
@@ -36,7 +36,7 @@
 #include "DirectoryReaderSync.h"
 #include "EntrySync.h"
 #include "FileEntrySync.h"
-#include "NotImplemented.h"
+#include "SyncCallbackHelper.h"
 
 namespace WebCore {
 
@@ -50,18 +50,26 @@ PassRefPtr<DirectoryReaderSync> DirectoryEntrySync::createReader(ExceptionCode&)
     return DirectoryReaderSync::create(m_fileSystem, m_fullPath);
 }
 
-PassRefPtr<FileEntrySync> DirectoryEntrySync::getFile(const String&, PassRefPtr<Flags>, ExceptionCode&)
+PassRefPtr<FileEntrySync> DirectoryEntrySync::getFile(const String& path, PassRefPtr<Flags> flags, ExceptionCode& ec)
 {
-    // FIXME: to be implemented.
-    notImplemented();
-    return 0;
+    ec = 0;
+    EntrySyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->getFile(this, path, flags, helper.successCallback(), helper.errorCallback())) {
+        ec = INVALID_MODIFICATION_ERR;
+        return 0;
+    }
+    return static_pointer_cast<FileEntrySync>(helper.getResult(ec));
 }
 
-PassRefPtr<DirectoryEntrySync> DirectoryEntrySync::getDirectory(const String&, PassRefPtr<Flags>, ExceptionCode&)
+PassRefPtr<DirectoryEntrySync> DirectoryEntrySync::getDirectory(const String& path, PassRefPtr<Flags> flags, ExceptionCode& ec)
 {
-    // FIXME: to be implemented.
-    notImplemented();
-    return 0;
+    ec = 0;
+    EntrySyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->getDirectory(this, path, flags, helper.successCallback(), helper.errorCallback())) {
+        ec = INVALID_MODIFICATION_ERR;
+        return 0;
+    }
+    return static_pointer_cast<DirectoryEntrySync>(helper.getResult(ec));
 }
 
 }
diff --git a/WebCore/fileapi/DirectoryReaderSync.cpp b/WebCore/fileapi/DirectoryReaderSync.cpp
index 600ab7f..6c66a15 100644
--- a/WebCore/fileapi/DirectoryReaderSync.cpp
+++ b/WebCore/fileapi/DirectoryReaderSync.cpp
@@ -33,9 +33,14 @@
 
 #if ENABLE(FILE_SYSTEM)
 
+#include "DirectoryEntry.h"
+#include "DirectoryEntrySync.h"
 #include "EntryArraySync.h"
+#include "EntrySync.h"
 #include "ExceptionCode.h"
-#include "NotImplemented.h"
+#include "FileEntrySync.h"
+#include "FileError.h"
+#include "SyncCallbackHelper.h"
 
 namespace WebCore {
 
@@ -44,10 +49,19 @@ DirectoryReaderSync::DirectoryReaderSync(DOMFileSystemBase* fileSystem, const St
 {
 }
 
-PassRefPtr<EntryArraySync> DirectoryReaderSync::readEntries(ExceptionCode&)
+PassRefPtr<EntryArraySync> DirectoryReaderSync::readEntries(ExceptionCode& ec)
 {
-    notImplemented();
-    return 0;
+    ec = 0;
+    if (!m_hasMoreEntries)
+        return EntryArraySync::create();
+
+    EntriesSyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->readDirectory(this, m_fullPath, helper.successCallback(), helper.errorCallback())) {
+        ec = INVALID_MODIFICATION_ERR;
+        setHasMoreEntries(false);
+        return 0;
+    }
+    return helper.getResult(ec);
 }
 
 } // namespace
diff --git a/WebCore/fileapi/Entry.cpp b/WebCore/fileapi/Entry.cpp
index 97a3270..2183b33 100644
--- a/WebCore/fileapi/Entry.cpp
+++ b/WebCore/fileapi/Entry.cpp
@@ -32,44 +32,54 @@
 
 #if ENABLE(FILE_SYSTEM)
 
-#include "DOMFilePath.h"
-#include "DOMFileSystem.h"
+#include "DirectoryEntry.h"
 #include "EntryCallback.h"
 #include "ErrorCallback.h"
 #include "FileError.h"
+#include "FileSystemCallbacks.h"
 #include "MetadataCallback.h"
 #include "VoidCallback.h"
 
 namespace WebCore {
 
-Entry::Entry(DOMFileSystem* fileSystem, const String& fullPath)
+Entry::Entry(DOMFileSystemBase* fileSystem, const String& fullPath)
     : EntryBase(fileSystem, fullPath)
 {
 }
 
-void Entry::getMetadata(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+void Entry::getMetadata(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef)
 {
-    filesystem()->getMetadata(this, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->getMetadata(this, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
-void Entry::moveTo(PassRefPtr<Entry> parent, const String& name, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) const
+void Entry::moveTo(PassRefPtr<DirectoryEntry> parent, const String& name, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef) const
 {
-    filesystem()->move(this, parent, name, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->move(this, parent.get(), name, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
-void Entry::copyTo(PassRefPtr<Entry> parent, const String& name, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) const
+void Entry::copyTo(PassRefPtr<DirectoryEntry> parent, const String& name, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef) const
 {
-    filesystem()->copy(this, parent, name, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->copy(this, parent.get(), name, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
-void Entry::remove(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) const
+void Entry::remove(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef) const
 {
-    filesystem()->remove(this, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->remove(this, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
-void Entry::getParent(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) const
+void Entry::getParent(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallbackRef) const
 {
-    filesystem()->getParent(this, successCallback, errorCallback);
+    RefPtr<ErrorCallback> errorCallback(errorCallbackRef);
+    if (!m_fileSystem->getParent(this, successCallback, errorCallback))
+        filesystem()->scheduleCallback(errorCallback.release(), FileError::create(INVALID_MODIFICATION_ERR));
 }
 
 String Entry::toURI(const String&)
diff --git a/WebCore/fileapi/Entry.h b/WebCore/fileapi/Entry.h
index b75f1ed..1b33f37 100644
--- a/WebCore/fileapi/Entry.h
+++ b/WebCore/fileapi/Entry.h
@@ -40,27 +40,27 @@
 
 namespace WebCore {
 
+class DirectoryEntry;
 class EntryCallback;
+class EntrySync;
 class ErrorCallback;
 class MetadataCallback;
 class VoidCallback;
 
 class Entry : public EntryBase {
 public:
-    virtual ~Entry() { }
-
     DOMFileSystem* filesystem() const { return static_cast<DOMFileSystem*>(m_fileSystem); }
 
     virtual void getMetadata(PassRefPtr<MetadataCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0);
-    virtual void moveTo(PassRefPtr<Entry> parent, const String& name = String(), PassRefPtr<EntryCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0) const;
-    virtual void copyTo(PassRefPtr<Entry> parent, const String& name = String(), PassRefPtr<EntryCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0) const;
+    virtual void moveTo(PassRefPtr<DirectoryEntry> parent, const String& name = String(), PassRefPtr<EntryCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0) const;
+    virtual void copyTo(PassRefPtr<DirectoryEntry> parent, const String& name = String(), PassRefPtr<EntryCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0) const;
     virtual void remove(PassRefPtr<VoidCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0) const;
     virtual void getParent(PassRefPtr<EntryCallback> successCallback = 0, PassRefPtr<ErrorCallback> errorCallback = 0) const;
 
     virtual String toURI(const String& mimeType = String());
 
 protected:
-    Entry(DOMFileSystem* fileSystem, const String& fullPath);
+    Entry(DOMFileSystemBase*, const String& fullPath);
 };
 
 } // namespace WebCore
diff --git a/WebCore/fileapi/Entry.idl b/WebCore/fileapi/Entry.idl
index d363bcd..f6fcdb3 100644
--- a/WebCore/fileapi/Entry.idl
+++ b/WebCore/fileapi/Entry.idl
@@ -41,8 +41,8 @@ module storage {
         readonly attribute DOMFileSystem filesystem;
 
         void getMetadata(in [Optional, Callback] MetadataCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
-        void moveTo(in Entry parent, in [Optional, ConvertUndefinedOrNullToNullString] DOMString name, in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
-        void copyTo(in Entry parent, in [Optional, ConvertUndefinedOrNullToNullString] DOMString name, in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
+        void moveTo(in DirectoryEntry parent, in [Optional, ConvertUndefinedOrNullToNullString] DOMString name, in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
+        void copyTo(in DirectoryEntry parent, in [Optional, ConvertUndefinedOrNullToNullString] DOMString name, in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
         void remove(in [Optional, Callback] VoidCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
         void getParent(in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
     };
diff --git a/WebCore/fileapi/EntryArraySync.cpp b/WebCore/fileapi/EntryArraySync.cpp
index 99ec7d3..1e2fa91 100644
--- a/WebCore/fileapi/EntryArraySync.cpp
+++ b/WebCore/fileapi/EntryArraySync.cpp
@@ -33,8 +33,20 @@
 
 #if ENABLE(FILE_SYSTEM)
 
+#include "EntryArray.h"
+
 namespace WebCore {
 
+PassRefPtr<EntryArraySync> EntryArraySync::create(EntryArray* entries)
+{
+    RefPtr<EntryArraySync> entriesSync = adoptRef(new EntryArraySync());
+    if (entries) {
+        for (unsigned i = 0; i < entries->length(); ++i)
+            entriesSync->append(EntrySync::create(entries->item(i)));
+    }
+    return entriesSync.release();
+}
+
 EntryArraySync::EntryArraySync()
 {
 }
diff --git a/WebCore/fileapi/EntryArraySync.h b/WebCore/fileapi/EntryArraySync.h
index 6d0524d..46cf409 100644
--- a/WebCore/fileapi/EntryArraySync.h
+++ b/WebCore/fileapi/EntryArraySync.h
@@ -48,6 +48,8 @@ public:
         return adoptRef(new EntryArraySync());
     }
 
+    static PassRefPtr<EntryArraySync> create(EntryArray*);
+
     unsigned length() const { return m_entries.size(); }
     EntrySync* item(unsigned index) const;
 
diff --git a/WebCore/fileapi/EntryBase.h b/WebCore/fileapi/EntryBase.h
index eee65df..6abf74f 100644
--- a/WebCore/fileapi/EntryBase.h
+++ b/WebCore/fileapi/EntryBase.h
@@ -48,6 +48,8 @@ class EntryBase : public RefCounted<EntryBase> {
 public:
     virtual ~EntryBase() { }
 
+    DOMFileSystemBase* filesystem() const { return m_fileSystem; }
+
     virtual bool isFile() const { return false; }
     virtual bool isDirectory() const { return false; }
 
diff --git a/WebCore/fileapi/EntrySync.cpp b/WebCore/fileapi/EntrySync.cpp
index 7da307c..b888613 100644
--- a/WebCore/fileapi/EntrySync.cpp
+++ b/WebCore/fileapi/EntrySync.cpp
@@ -34,37 +34,62 @@
 #if ENABLE(FILE_SYSTEM)
 
 #include "DOMFilePath.h"
+#include "DOMFileSystemSync.h"
+#include "DirectoryEntry.h"
 #include "DirectoryEntrySync.h"
+#include "FileEntrySync.h"
 #include "Metadata.h"
-#include "NotImplemented.h"
+#include "SyncCallbackHelper.h"
 
 namespace WebCore {
 
-PassRefPtr<Metadata> EntrySync::getMetadata(ExceptionCode&)
+PassRefPtr<EntrySync> EntrySync::create(EntryBase* entry)
 {
-    // FIXME: to be implemented.
-    notImplemented();
-    return 0;
+    if (entry->isFile())
+        return adoptRef(new FileEntrySync(entry->m_fileSystem, entry->m_fullPath));
+    return adoptRef(new DirectoryEntrySync(entry->m_fileSystem, entry->m_fullPath));
 }
 
-PassRefPtr<EntrySync> EntrySync::moveTo(PassRefPtr<DirectoryEntrySync>, const String&, ExceptionCode&) const
+PassRefPtr<Metadata> EntrySync::getMetadata(ExceptionCode& ec)
 {
-    // FIXME: to be implemented.
-    notImplemented();
-    return 0;
+    ec = 0;
+    MetadataSyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->getMetadata(this, helper.successCallback(), helper.errorCallback())) {
+        ec = INVALID_MODIFICATION_ERR;
+        return 0;
+    }
+    return helper.getResult(ec);
 }
 
-PassRefPtr<EntrySync> EntrySync::copyTo(PassRefPtr<DirectoryEntrySync>, const String&, ExceptionCode&) const
+PassRefPtr<EntrySync> EntrySync::moveTo(PassRefPtr<DirectoryEntrySync> parent, const String& name, ExceptionCode& ec) const
 {
-    // FIXME: to be implemented.
-    notImplemented();
-    return 0;
+    ec = 0;
+    EntrySyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->move(this, parent.get(), name, helper.successCallback(), helper.errorCallback())) {
+        ec = INVALID_MODIFICATION_ERR;
+        return 0;
+    }
+    return helper.getResult(ec);
 }
 
-void EntrySync::remove(ExceptionCode&) const
+PassRefPtr<EntrySync> EntrySync::copyTo(PassRefPtr<DirectoryEntrySync> parent, const String& name, ExceptionCode& ec) const
 {
-    // FIXME: to be implemented.
-    notImplemented();
+    ec = 0;
+    EntrySyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->copy(this, parent.get(), name, helper.successCallback(), helper.errorCallback())) {
+        ec = INVALID_MODIFICATION_ERR;
+        return 0;
+    }
+    return helper.getResult(ec);
+}
+
+void EntrySync::remove(ExceptionCode& ec) const
+{
+    ec = 0;
+    VoidSyncCallbackHelper helper(m_fileSystem->asyncFileSystem());
+    if (!m_fileSystem->remove(this, helper.successCallback(), helper.errorCallback()))
+        ec = INVALID_MODIFICATION_ERR;
+    helper.getResult(ec);
 }
 
 PassRefPtr<EntrySync> EntrySync::getParent() const
diff --git a/WebCore/fileapi/EntrySync.h b/WebCore/fileapi/EntrySync.h
index 10b1101..618f12c 100644
--- a/WebCore/fileapi/EntrySync.h
+++ b/WebCore/fileapi/EntrySync.h
@@ -47,6 +47,8 @@ class Metadata;
 
 class EntrySync : public EntryBase {
 public:
+    static PassRefPtr<EntrySync> create(EntryBase*);
+
     DOMFileSystemSync* filesystem() const { return static_cast<DOMFileSystemSync*>(m_fileSystem); }
 
     virtual PassRefPtr<Metadata> getMetadata(ExceptionCode&);
diff --git a/WebCore/fileapi/FileEntry.cpp b/WebCore/fileapi/FileEntry.cpp
index a7e7158..c7478fb 100644
--- a/WebCore/fileapi/FileEntry.cpp
+++ b/WebCore/fileapi/FileEntry.cpp
@@ -41,7 +41,7 @@
 
 namespace WebCore {
 
-FileEntry::FileEntry(DOMFileSystem* fileSystem, const String& fullPath)
+FileEntry::FileEntry(DOMFileSystemBase* fileSystem, const String& fullPath)
     : Entry(fileSystem, fullPath)
 {
 }
diff --git a/WebCore/fileapi/FileEntry.h b/WebCore/fileapi/FileEntry.h
index 2c85d73..216cca2 100644
--- a/WebCore/fileapi/FileEntry.h
+++ b/WebCore/fileapi/FileEntry.h
@@ -39,11 +39,11 @@
 
 namespace WebCore {
 
-class DOMFileSystem;
+class DOMFileSystemBase;
 
 class FileEntry : public Entry {
 public:
-    static PassRefPtr<FileEntry> create(DOMFileSystem* fileSystem, const String& fullPath)
+    static PassRefPtr<FileEntry> create(DOMFileSystemBase* fileSystem, const String& fullPath)
     {
         return adoptRef(new FileEntry(fileSystem, fullPath));
     }
@@ -54,7 +54,7 @@ public:
     virtual bool isFile() const { return true; }
 
 private:
-    FileEntry(DOMFileSystem* fileSystem, const String& fullPath);
+    FileEntry(DOMFileSystemBase* fileSystem, const String& fullPath);
 };
 
 } // namespace
diff --git a/WebCore/fileapi/FileSystemCallbacks.cpp b/WebCore/fileapi/FileSystemCallbacks.cpp
index 83b120b..e5f404e 100644
--- a/WebCore/fileapi/FileSystemCallbacks.cpp
+++ b/WebCore/fileapi/FileSystemCallbacks.cpp
@@ -36,7 +36,7 @@
 #include "AsyncFileSystem.h"
 #include "AsyncFileWriter.h"
 #include "DOMFilePath.h"
-#include "DOMFileSystem.h"
+#include "DOMFileSystemBase.h"
 #include "DirectoryEntry.h"
 #include "DirectoryReader.h"
 #include "EntriesCallback.h"
@@ -111,12 +111,12 @@ void FileSystemCallbacksBase::didFail(int code)
 
 // EntryCallbacks -------------------------------------------------------------
 
-PassOwnPtr<EntryCallbacks> EntryCallbacks::create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystem* fileSystem, const String& expectedPath, bool isDirectory)
+PassOwnPtr<EntryCallbacks> EntryCallbacks::create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystemBase* fileSystem, const String& expectedPath, bool isDirectory)
 {
     return adoptPtr(new EntryCallbacks(successCallback, errorCallback, fileSystem, expectedPath, isDirectory));
 }
 
-EntryCallbacks::EntryCallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystem* fileSystem, const String& expectedPath, bool isDirectory)
+EntryCallbacks::EntryCallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystemBase* fileSystem, const String& expectedPath, bool isDirectory)
     : FileSystemCallbacksBase(errorCallback)
     , m_successCallback(successCallback)
     , m_fileSystem(fileSystem)
@@ -138,12 +138,12 @@ void EntryCallbacks::didSucceed()
 
 // EntriesCallbacks -----------------------------------------------------------
 
-PassOwnPtr<EntriesCallbacks> EntriesCallbacks::create(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DirectoryReader* directoryReader, const String& basePath)
+PassOwnPtr<EntriesCallbacks> EntriesCallbacks::create(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DirectoryReaderBase* directoryReader, const String& basePath)
 {
     return adoptPtr(new EntriesCallbacks(successCallback, errorCallback, directoryReader, basePath));
 }
 
-EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DirectoryReader* directoryReader, const String& basePath)
+EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DirectoryReaderBase* directoryReader, const String& basePath)
     : FileSystemCallbacksBase(errorCallback)
     , m_successCallback(successCallback)
     , m_directoryReader(directoryReader)
diff --git a/WebCore/fileapi/FileSystemCallbacks.h b/WebCore/fileapi/FileSystemCallbacks.h
index 7f186ef..c600a76 100644
--- a/WebCore/fileapi/FileSystemCallbacks.h
+++ b/WebCore/fileapi/FileSystemCallbacks.h
@@ -41,8 +41,8 @@
 namespace WebCore {
 
 class AsyncFileWriter;
-class DOMFileSystem;
-class DirectoryReader;
+class DOMFileSystemBase;
+class DirectoryReaderBase;
 class ErrorCallback;
 class EntriesCallback;
 class EntryArray;
@@ -86,27 +86,27 @@ protected:
 
 class EntryCallbacks : public FileSystemCallbacksBase {
 public:
-    static PassOwnPtr<EntryCallbacks> create(PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>, DOMFileSystem*, const String& expectedPath, bool isDirectory);
+    static PassOwnPtr<EntryCallbacks> create(PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>, DOMFileSystemBase*, const String& expectedPath, bool isDirectory);
     virtual void didSucceed();
 
 private:
-    EntryCallbacks(PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>, DOMFileSystem*, const String& expectedPath, bool isDirectory);
+    EntryCallbacks(PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>, DOMFileSystemBase*, const String& expectedPath, bool isDirectory);
     RefPtr<EntryCallback> m_successCallback;
-    DOMFileSystem* m_fileSystem;
+    DOMFileSystemBase* m_fileSystem;
     String m_expectedPath;
     bool m_isDirectory;
 };
 
 class EntriesCallbacks : public FileSystemCallbacksBase {
 public:
-    static PassOwnPtr<EntriesCallbacks> create(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DirectoryReader*, const String& basePath);
+    static PassOwnPtr<EntriesCallbacks> create(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DirectoryReaderBase*, const String& basePath);
     virtual void didReadDirectoryEntry(const String& name, bool isDirectory);
     virtual void didReadDirectoryEntries(bool hasMore);
 
 private:
-    EntriesCallbacks(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DirectoryReader*, const String& basePath);
+    EntriesCallbacks(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DirectoryReaderBase*, const String& basePath);
     RefPtr<EntriesCallback> m_successCallback;
-    DirectoryReader* m_directoryReader;
+    DirectoryReaderBase* m_directoryReader;
     String m_basePath;
     RefPtr<EntryArray> m_entries;
 };
diff --git a/WebCore/fileapi/LocalFileSystem.cpp b/WebCore/fileapi/LocalFileSystem.cpp
index 567aafe..c7347b8 100644
--- a/WebCore/fileapi/LocalFileSystem.cpp
+++ b/WebCore/fileapi/LocalFileSystem.cpp
@@ -81,7 +81,7 @@ static void openFileSystem(ScriptExecutionContext*, const String& basePath, cons
     AsyncFileSystem::openFileSystem(basePath, identifier, type, callbacks);
 }
 
-void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long, PassOwnPtr<AsyncFileSystemCallbacks> callbacks, bool)
 {
     // AsyncFileSystem::openFileSystem calls callbacks synchronously, so the method needs to be called asynchronously.
     context->postTask(createCallbackTask(&openFileSystem, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, callbacks));
diff --git a/WebCore/fileapi/LocalFileSystem.h b/WebCore/fileapi/LocalFileSystem.h
index bb1d045..9d8ae65 100644
--- a/WebCore/fileapi/LocalFileSystem.h
+++ b/WebCore/fileapi/LocalFileSystem.h
@@ -52,7 +52,7 @@ public:
     // calling this one.
     static LocalFileSystem& localFileSystem();
 
-    void requestFileSystem(ScriptExecutionContext*, AsyncFileSystem::Type, long long size, PassOwnPtr<AsyncFileSystemCallbacks>);
+    void requestFileSystem(ScriptExecutionContext*, AsyncFileSystem::Type, long long size, PassOwnPtr<AsyncFileSystemCallbacks>, bool synchronous = false);
 
 #if !PLATFORM(CHROMIUM)
     // This call is not thread-safe; must be called before any worker threads are created.
diff --git a/WebCore/fileapi/Metadata.h b/WebCore/fileapi/Metadata.h
index 1fec943..b70806b 100644
--- a/WebCore/fileapi/Metadata.h
+++ b/WebCore/fileapi/Metadata.h
@@ -44,6 +44,11 @@ public:
         return adoptRef(new Metadata(modificationTime));
     }
 
+    static PassRefPtr<Metadata> create(Metadata* metadata)
+    {
+        return adoptRef(new Metadata(metadata->m_modificationTime));
+    }
+
     // Needs to return epoch time in milliseconds for Date.
     double modificationTime() const { return m_modificationTime * 1000.0; }
 
diff --git a/WebCore/fileapi/SyncCallbackHelper.h b/WebCore/fileapi/SyncCallbackHelper.h
new file mode 100644
index 0000000..1612e93
--- /dev/null
+++ b/WebCore/fileapi/SyncCallbackHelper.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SyncCallbackHelper_h
+#define SyncCallbackHelper_h
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "DirectoryEntry.h"
+#include "EntriesCallback.h"
+#include "EntryArraySync.h"
+#include "EntryCallback.h"
+#include "ErrorCallback.h"
+#include "ExceptionCode.h"
+#include "FileEntry.h"
+#include "FileError.h"
+#include "FileSystemCallback.h"
+#include "MetadataCallback.h"
+#include "VoidCallback.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class AsyncFileSystem;
+class DirectoryEntrySync;
+class EntryArraySync;
+class EntrySync;
+class FileEntrySync;
+
+// A helper template for FileSystemSync implementation.
+template <typename SuccessCallback, typename ObserverType, typename CallbackArg, typename ResultType>
+class SyncCallbackHelper : public Noncopyable {
+public:
+    typedef SyncCallbackHelper<SuccessCallback, ObserverType, CallbackArg, ResultType> HelperType;
+    SyncCallbackHelper(ObserverType* observer = 0)
+        : m_observer(observer)
+        , m_successCallback(SuccessCallbackImpl::create(this))
+        , m_errorCallback(ErrorCallbackImpl::create(this))
+        , m_error(0)
+        , m_completed(false)
+    {
+    }
+
+    PassRefPtr<ResultType> getResult(ExceptionCode& ec)
+    {
+        if (m_observer) {
+            while (!m_completed) {
+                if (!m_observer->waitForOperationToComplete()) {
+                    m_error = ABORT_ERR;
+                    break;
+                }
+            }
+        }
+        ec = m_error;
+        return m_result.release();
+    }
+
+    PassRefPtr<SuccessCallback> successCallback() { return m_successCallback; }
+    PassRefPtr<ErrorCallback> errorCallback() { return m_errorCallback; }
+
+private:
+    class SuccessCallbackImpl : public SuccessCallback {
+    public:
+        static PassRefPtr<SuccessCallbackImpl> create(HelperType* helper)
+        {
+            return adoptRef(new SuccessCallbackImpl(helper));
+        }
+
+        virtual void handleEvent()
+        {
+            m_helper->setError(0);
+        }
+
+        virtual bool handleEvent(CallbackArg* arg)
+        {
+            m_helper->setResult(ResultType::create(arg));
+            return true;
+        }
+
+    private:
+        SuccessCallbackImpl(HelperType* helper)
+            : m_helper(helper)
+        {
+        }
+        HelperType* m_helper;
+    };
+
+    class ErrorCallbackImpl : public ErrorCallback {
+    public:
+        static PassRefPtr<ErrorCallbackImpl> create(HelperType* helper)
+        {
+            return adoptRef(new ErrorCallbackImpl(helper));
+        }
+
+        virtual bool handleEvent(FileError* error)
+        {
+            ASSERT(error);
+            m_helper->setError(error->code());
+            return true;
+        }
+
+    private:
+        ErrorCallbackImpl(HelperType* helper)
+            : m_helper(helper)
+        {
+        }
+        HelperType* m_helper;
+    };
+
+    friend class SuccessCallbackImpl;
+    friend class ErrorCallbackImpl;
+
+    void setError(ExceptionCode ec)
+    {
+        m_error = ec;
+        m_completed = true;
+    }
+
+    void setResult(PassRefPtr<ResultType> result)
+    {
+        m_result = result;
+        m_completed = true;
+    }
+
+    ObserverType* m_observer;
+    RefPtr<SuccessCallbackImpl> m_successCallback;
+    RefPtr<ErrorCallbackImpl> m_errorCallback;
+    RefPtr<ResultType> m_result;
+    ExceptionCode m_error;
+    bool m_completed;
+};
+
+struct EmptyType : public RefCounted<EmptyType> {
+    static PassRefPtr<EmptyType> create(EmptyType*)
+    {
+        return 0;
+    }
+};
+
+struct EmptyObserverType {
+    bool waitForOperationToComplete()
+    {
+        return false;
+    }
+};
+
+typedef SyncCallbackHelper<EntryCallback, AsyncFileSystem, Entry, EntrySync> EntrySyncCallbackHelper;
+typedef SyncCallbackHelper<EntriesCallback, AsyncFileSystem, EntryArray, EntryArraySync> EntriesSyncCallbackHelper;
+typedef SyncCallbackHelper<MetadataCallback, AsyncFileSystem, Metadata, Metadata> MetadataSyncCallbackHelper;
+typedef SyncCallbackHelper<VoidCallback, AsyncFileSystem, EmptyType, EmptyType> VoidSyncCallbackHelper;
+typedef SyncCallbackHelper<FileSystemCallback, EmptyObserverType, DOMFileSystem, DOMFileSystemSync> FileSystemSyncCallbackHelper;
+
+} // namespace WebCore
+
+#endif // ENABLE(FILE_SYSTEM)
+
+#endif // SyncCallbackHelper_h
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index 8cac879..86b72e5 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -192,7 +192,7 @@ module window {
 #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);
+        [EnabledAtRuntime=FileSystem] 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/platform/AsyncFileSystem.h b/WebCore/platform/AsyncFileSystem.h
index 1bf7580..27c6240 100644
--- a/WebCore/platform/AsyncFileSystem.h
+++ b/WebCore/platform/AsyncFileSystem.h
@@ -59,6 +59,10 @@ public:
 
     static bool isAvailable();
 
+    // Subclass must implement this if it supports synchronous operations.
+    // This should return false if there are no pending operations.
+    virtual bool waitForOperationToComplete() { return false; }
+
     // Creates and returns a new platform-specific AsyncFileSystem instance if the platform has its own implementation.
     static PassOwnPtr<AsyncFileSystem> create(const String& rootPath);
 
diff --git a/WebCore/workers/WorkerContext.cpp b/WebCore/workers/WorkerContext.cpp
index 6cee246..ea1ba89 100644
--- a/WebCore/workers/WorkerContext.cpp
+++ b/WebCore/workers/WorkerContext.cpp
@@ -66,11 +66,13 @@
 #if ENABLE(FILE_SYSTEM)
 #include "AsyncFileSystem.h"
 #include "DOMFileSystem.h"
+#include "DOMFileSystemSync.h"
 #include "ErrorCallback.h"
 #include "FileError.h"
 #include "FileSystemCallback.h"
 #include "FileSystemCallbacks.h"
 #include "LocalFileSystem.h"
+#include "SyncCallbackHelper.h"
 #endif
 
 namespace WebCore {
@@ -366,6 +368,25 @@ void WorkerContext::requestFileSystem(int type, long long size, PassRefPtr<FileS
     LocalFileSystem::localFileSystem().requestFileSystem(this, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, this));
 }
 
+PassRefPtr<DOMFileSystemSync> WorkerContext::requestFileSystemSync(int type, long long size, ExceptionCode& ec)
+{
+    ec = 0;
+    if (!AsyncFileSystem::isAvailable() || !securityOrigin()->canAccessFileSystem()) {
+        ec = SECURITY_ERR;
+        return 0;
+    }
+
+    AsyncFileSystem::Type fileSystemType = static_cast<AsyncFileSystem::Type>(type);
+    if (fileSystemType != AsyncFileSystem::Temporary && fileSystemType != AsyncFileSystem::Persistent) {
+        ec = INVALID_MODIFICATION_ERR;
+        return 0;
+    }
+
+    FileSystemSyncCallbackHelper helper;
+    LocalFileSystem::localFileSystem().requestFileSystem(this, fileSystemType, size, FileSystemCallbacks::create(helper.successCallback(), helper.errorCallback(), this), true);
+    return helper.getResult(ec);
+}
+
 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
diff --git a/WebCore/workers/WorkerContext.h b/WebCore/workers/WorkerContext.h
index 4128a56..08804d2 100644
--- a/WebCore/workers/WorkerContext.h
+++ b/WebCore/workers/WorkerContext.h
@@ -45,6 +45,7 @@
 namespace WebCore {
 
     class Blob;
+    class DOMFileSystemSync;
     class Database;
     class DatabaseCallback;
     class DatabaseSync;
@@ -130,6 +131,7 @@ namespace WebCore {
             PERSISTENT,
         };
         void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
+        PassRefPtr<DOMFileSystemSync> requestFileSystemSync(int type, long long size, ExceptionCode&);
 #endif
 
         // These methods are used for GC marking. See JSWorkerContext::markChildren(MarkStack&) in
diff --git a/WebCore/workers/WorkerContext.idl b/WebCore/workers/WorkerContext.idl
index 3e185c0..aa40ff3 100644
--- a/WebCore/workers/WorkerContext.idl
+++ b/WebCore/workers/WorkerContext.idl
@@ -108,7 +108,8 @@ module threads {
 #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);
+        [EnabledAtRuntime=FileSystem] void requestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
+        [EnabledAtRuntime=FileSystem] DOMFileSystemSync requestFileSystemSync(in unsigned short type, in long long size) raises (FileException);
 
                  attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags;
 #endif
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 71937e8..bc940de 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,43 @@
+2010-10-06  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Add FileSystemSync implementation for Worker
+        https://bugs.webkit.org/show_bug.cgi?id=47044
+
+        * src/LocalFileSystemChromium.cpp:
+        (WebCore::LocalFileSystem::requestFileSystem): Added a new parameter
+        for synchronous mode.
+        * src/WebFileSystemCallbacksImpl.cpp:
+        (WebKit::WebFileSystemCallbacksImpl::WebFileSystemCallbacksImpl): Added
+        a parameter for synchronous mode.
+        (WebKit::WebFileSystemCallbacksImpl::didOpenFileSystem): Changed to
+        creates WorkerAsyncFileSystemChromium with synchronous flag.
+        * src/WebFileSystemCallbacksImpl.h:
+        * src/WebWorkerBase.cpp:
+        (WebKit::WebWorkerBase::openFileSystem): Added a parameter for
+        synchronous mode.
+        * src/WebWorkerBase.h:
+        * src/WorkerAsyncFileSystemChromium.cpp:
+        (WebCore::WorkerAsyncFileSystemChromium::WorkerAsyncFileSystemChromium):
+        (WebCore::WorkerAsyncFileSystemChromium::waitForOperationToComplete):
+        Added.
+        (WebCore::WorkerAsyncFileSystemChromium::move):
+        (WebCore::WorkerAsyncFileSystemChromium::copy):
+        (WebCore::WorkerAsyncFileSystemChromium::remove):
+        (WebCore::WorkerAsyncFileSystemChromium::readMetadata):
+        (WebCore::WorkerAsyncFileSystemChromium::createFile):
+        (WebCore::WorkerAsyncFileSystemChromium::createDirectory):
+        (WebCore::WorkerAsyncFileSystemChromium::fileExists):
+        (WebCore::WorkerAsyncFileSystemChromium::directoryExists):
+        (WebCore::WorkerAsyncFileSystemChromium::readDirectory):
+        (WebCore::WorkerAsyncFileSystemChromium::createWorkerFileSystemCallbacksBridge):
+        Updated to store the created bridge in a member variable so that
+        we can call bridge->stop() later when the RunLoop is terminating.
+        * src/WorkerAsyncFileSystemChromium.h:
+        (WebCore::WorkerAsyncFileSystemChromium::create): Added a new
+        parameter for synchronous mode.
+
 2010-10-06  Andrei Popescu  <andreip at google.com>
 
         Reviewed by Jeremy Orlow.
diff --git a/WebKit/chromium/src/LocalFileSystemChromium.cpp b/WebKit/chromium/src/LocalFileSystemChromium.cpp
index a4f2d72..25b1feb 100644
--- a/WebKit/chromium/src/LocalFileSystemChromium.cpp
+++ b/WebKit/chromium/src/LocalFileSystemChromium.cpp
@@ -57,7 +57,7 @@ LocalFileSystem& LocalFileSystem::localFileSystem()
     return *localFileSystem;
 }
 
-void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long size, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long size, PassOwnPtr<AsyncFileSystemCallbacks> callbacks, bool synchronous)
 {
     ASSERT(context);
     if (context->isDocument()) {
@@ -68,7 +68,7 @@ void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFi
         WorkerContext* workerContext = static_cast<WorkerContext*>(context);
         WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy();
         WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerLoaderProxy);
-        webWorker->openFileSystem(static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(callbacks, context));
+        webWorker->openFileSystem(static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(callbacks, context, synchronous), synchronous);
     }
 }
 
diff --git a/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp b/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp
index 6b8c80f..f44e8f1 100644
--- a/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp
+++ b/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp
@@ -45,9 +45,10 @@ using namespace WebCore;
 
 namespace WebKit {
 
-WebFileSystemCallbacksImpl::WebFileSystemCallbacksImpl(PassOwnPtr<AsyncFileSystemCallbacks> callbacks, WebCore::ScriptExecutionContext* context)
+WebFileSystemCallbacksImpl::WebFileSystemCallbacksImpl(PassOwnPtr<AsyncFileSystemCallbacks> callbacks, WebCore::ScriptExecutionContext* context, bool synchronous)
     : m_callbacks(callbacks)
     , m_context(context)
+    , m_synchronous(synchronous)
 {
     ASSERT(m_callbacks);
 }
@@ -79,7 +80,7 @@ void WebFileSystemCallbacksImpl::didReadDirectory(const WebVector<WebFileSystemE
 void WebFileSystemCallbacksImpl::didOpenFileSystem(const WebString& name, const WebString& path)
 {
     if (m_context && m_context->isWorkerContext())
-        m_callbacks->didOpenFileSystem(name, WorkerAsyncFileSystemChromium::create(m_context, path));
+        m_callbacks->didOpenFileSystem(name, WorkerAsyncFileSystemChromium::create(m_context, path, m_synchronous));
     else
         m_callbacks->didOpenFileSystem(name, AsyncFileSystemChromium::create(path));
     delete this;
diff --git a/WebKit/chromium/src/WebFileSystemCallbacksImpl.h b/WebKit/chromium/src/WebFileSystemCallbacksImpl.h
index 947fd2f..75fa2bb 100644
--- a/WebKit/chromium/src/WebFileSystemCallbacksImpl.h
+++ b/WebKit/chromium/src/WebFileSystemCallbacksImpl.h
@@ -49,7 +49,7 @@ class WebString;
 
 class WebFileSystemCallbacksImpl : public WebFileSystemCallbacks {
 public:
-    WebFileSystemCallbacksImpl(PassOwnPtr<WebCore::AsyncFileSystemCallbacks>, WebCore::ScriptExecutionContext* = 0);
+    WebFileSystemCallbacksImpl(PassOwnPtr<WebCore::AsyncFileSystemCallbacks>, WebCore::ScriptExecutionContext* = 0, bool synchronous = false);
     virtual ~WebFileSystemCallbacksImpl();
 
     virtual void didSucceed();
@@ -63,6 +63,7 @@ private:
 
     // Used for worker's openFileSystem callbacks.
     WebCore::ScriptExecutionContext* m_context;
+    bool m_synchronous;
 };
 
 } // namespace WebKit
diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp
index f4f5921..de4858c 100644
--- a/WebKit/chromium/src/WebWorkerBase.cpp
+++ b/WebKit/chromium/src/WebWorkerBase.cpp
@@ -237,11 +237,23 @@ bool WebWorkerBase::allowDatabase(WebFrame*, const WebString& name, const WebStr
 }
 
 #if ENABLE(FILE_SYSTEM)
-void WebWorkerBase::openFileSystem(WebFileSystem::Type type, long long size, WebFileSystemCallbacks* callbacks)
+void WebWorkerBase::openFileSystem(WebFileSystem::Type type, long long size, WebFileSystemCallbacks* callbacks, bool synchronous)
 {
+    WorkerRunLoop& runLoop = m_workerThread->runLoop();
     WorkerScriptController* controller = WorkerScriptController::controllerForContext();
-    RefPtr<WorkerFileSystemCallbacksBridge> bridge = WorkerFileSystemCallbacksBridge::create(this, controller->workerContext(), callbacks);
-    bridge->postOpenFileSystemToMainThread(commonClient(), type, size, openFileSystemMode);
+    WorkerContext* workerContext = controller->workerContext();
+
+    // Create a unique mode for this openFileSystem call.
+    String mode = openFileSystemMode;
+    mode.append(String::number(runLoop.createUniqueId()));
+
+    RefPtr<WorkerFileSystemCallbacksBridge> bridge = WorkerFileSystemCallbacksBridge::create(this, workerContext, callbacks);
+    bridge->postOpenFileSystemToMainThread(commonClient(), type, size, mode);
+
+    if (synchronous) {
+        if (runLoop.runInMode(workerContext, mode) == MessageQueueTerminated)
+            bridge->stop();
+    }
 }
 #endif
 
diff --git a/WebKit/chromium/src/WebWorkerBase.h b/WebKit/chromium/src/WebWorkerBase.h
index 1f4bc03..fe84bf7 100644
--- a/WebKit/chromium/src/WebWorkerBase.h
+++ b/WebKit/chromium/src/WebWorkerBase.h
@@ -93,7 +93,7 @@ public:
 
 #if ENABLE(FILE_SYSTEM)
     // Requests to open a file system for this worker. (Note that this is not the implementation for WebFrameClient::openFileSystem.)
-    void openFileSystem(WebFileSystem::Type, long long size, WebFileSystemCallbacks*);
+    void openFileSystem(WebFileSystem::Type, long long size, WebFileSystemCallbacks*, bool synchronous);
 #endif
 
     // Executes the given task on the main thread.
diff --git a/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp b/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp
index b21b709..6c2d4ae 100644
--- a/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp
+++ b/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp
@@ -53,17 +53,17 @@ namespace WebCore {
 
 static const char fileSystemOperationsMode[] = "fileSystemOperationsMode";
 
-WorkerAsyncFileSystemChromium::WorkerAsyncFileSystemChromium(ScriptExecutionContext* context, const String& rootPath)
+WorkerAsyncFileSystemChromium::WorkerAsyncFileSystemChromium(ScriptExecutionContext* context, const String& rootPath, bool synchronous)
     : AsyncFileSystem(rootPath)
     , m_scriptExecutionContext(context)
     , m_webFileSystem(WebKit::webKitClient()->fileSystem())
-    , m_mode(fileSystemOperationsMode)
+    , m_workerContext(static_cast<WorkerContext*>(context))
+    , m_synchronous(synchronous)
 {
     ASSERT(m_webFileSystem);
     ASSERT(m_scriptExecutionContext->isWorkerContext());
 
-    WorkerContext* workerContext = static_cast<WorkerContext*>(context);
-    WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy();
+    WorkerLoaderProxy* workerLoaderProxy = &m_workerContext->thread()->workerLoaderProxy();
     m_worker = static_cast<WebWorkerBase*>(workerLoaderProxy);
 }
 
@@ -71,49 +71,62 @@ WorkerAsyncFileSystemChromium::~WorkerAsyncFileSystemChromium()
 {
 }
 
+bool WorkerAsyncFileSystemChromium::waitForOperationToComplete()
+{
+    if (!m_bridgeForCurrentOperation.get())
+        return false;
+
+    RefPtr<WorkerFileSystemCallbacksBridge> bridge = m_bridgeForCurrentOperation.release();
+    if (m_workerContext->thread()->runLoop().runInMode(m_workerContext, m_modeForCurrentOperation) == MessageQueueTerminated) {
+        bridge->stop();
+        return false;
+    }
+    return true;
+}
+
 void WorkerAsyncFileSystemChromium::move(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postMoveToMainThread(m_webFileSystem, sourcePath, destinationPath, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postMoveToMainThread(m_webFileSystem, sourcePath, destinationPath, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::copy(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postCopyToMainThread(m_webFileSystem, sourcePath, destinationPath, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postCopyToMainThread(m_webFileSystem, sourcePath, destinationPath, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::remove(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postRemoveToMainThread(m_webFileSystem, path, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postRemoveToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::readMetadata(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postReadMetadataToMainThread(m_webFileSystem, path, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postReadMetadataToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::createFile(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postCreateFileToMainThread(m_webFileSystem, path, exclusive, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postCreateFileToMainThread(m_webFileSystem, path, exclusive, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::createDirectory(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postCreateDirectoryToMainThread(m_webFileSystem, path, exclusive, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postCreateDirectoryToMainThread(m_webFileSystem, path, exclusive, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::fileExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postFileExistsToMainThread(m_webFileSystem, path, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postFileExistsToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::directoryExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postDirectoryExistsToMainThread(m_webFileSystem, path, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postDirectoryExistsToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::readDirectory(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    createWorkerFileSystemCallbacksBridge(callbacks)->postReadDirectoryToMainThread(m_webFileSystem, path, m_mode);
+    createWorkerFileSystemCallbacksBridge(callbacks)->postReadDirectoryToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
 }
 
 void WorkerAsyncFileSystemChromium::createWriter(AsyncFileWriterClient*, const String&, PassOwnPtr<AsyncFileSystemCallbacks>)
@@ -123,7 +136,13 @@ void WorkerAsyncFileSystemChromium::createWriter(AsyncFileWriterClient*, const S
 
 PassRefPtr<WorkerFileSystemCallbacksBridge> WorkerAsyncFileSystemChromium::createWorkerFileSystemCallbacksBridge(PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
 {
-    return WorkerFileSystemCallbacksBridge::create(m_worker, m_scriptExecutionContext, new WebFileSystemCallbacksImpl(callbacks));
+    ASSERT(!m_synchronous || !m_bridgeForCurrentOperation.get());
+
+    m_modeForCurrentOperation = fileSystemOperationsMode;
+    m_modeForCurrentOperation.append(String::number(m_workerContext->thread()->runLoop().createUniqueId()));
+
+    m_bridgeForCurrentOperation = WorkerFileSystemCallbacksBridge::create(m_worker, m_scriptExecutionContext, new WebKit::WebFileSystemCallbacksImpl(callbacks));
+    return m_bridgeForCurrentOperation;
 }
 
 } // namespace WebCore
diff --git a/WebKit/chromium/src/WorkerAsyncFileSystemChromium.h b/WebKit/chromium/src/WorkerAsyncFileSystemChromium.h
index 7cd34b9..5fc7646 100644
--- a/WebKit/chromium/src/WorkerAsyncFileSystemChromium.h
+++ b/WebKit/chromium/src/WorkerAsyncFileSystemChromium.h
@@ -48,16 +48,20 @@ namespace WebCore {
 
 class AsyncFileSystemCallbacks;
 class ScriptExecutionContext;
+class WorkerContext;
 
 class WorkerAsyncFileSystemChromium : public AsyncFileSystem {
 public:
-    static PassOwnPtr<AsyncFileSystem> create(ScriptExecutionContext* context, const String& rootPath)
+    static PassOwnPtr<AsyncFileSystem> create(ScriptExecutionContext* context, const String& rootPath, bool synchronous)
     {
-        return adoptPtr(new WorkerAsyncFileSystemChromium(context, rootPath));
+        return adoptPtr(new WorkerAsyncFileSystemChromium(context, rootPath, synchronous));
     }
 
     virtual ~WorkerAsyncFileSystemChromium();
 
+    // Runs one pending operation (to wait for completion in the sync-mode).
+    virtual bool waitForOperationToComplete();
+
     virtual void move(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks>);
     virtual void copy(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks>);
     virtual void remove(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>);
@@ -70,13 +74,17 @@ public:
     virtual void createWriter(AsyncFileWriterClient* client, const String& path, PassOwnPtr<AsyncFileSystemCallbacks>);
 
 private:
-    WorkerAsyncFileSystemChromium(ScriptExecutionContext*, const String& rootPath);
+    WorkerAsyncFileSystemChromium(ScriptExecutionContext*, const String& rootPath, bool synchronous);
+
     PassRefPtr<WebKit::WorkerFileSystemCallbacksBridge> createWorkerFileSystemCallbacksBridge(PassOwnPtr<AsyncFileSystemCallbacks>);
 
     ScriptExecutionContext* m_scriptExecutionContext;
     WebKit::WebFileSystem* m_webFileSystem;
     WebKit::WebWorkerBase* m_worker;
-    String m_mode;
+    WorkerContext* m_workerContext;
+    RefPtr<WebKit::WorkerFileSystemCallbacksBridge> m_bridgeForCurrentOperation;
+    String m_modeForCurrentOperation;
+    bool m_synchronous;
 };
 
 } // namespace WebCore

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list