| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/tools/test_shell/simple_file_writer.h" | 5 #include "webkit/tools/test_shell/simple_file_writer.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
| 9 #include "net/url_request/url_request_context.h" | 9 #include "net/url_request/url_request_context.h" |
| 10 #include "webkit/fileapi/file_system_callback_dispatcher.h" | 10 #include "webkit/fileapi/file_system_callback_dispatcher.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 URLRequestContext* SimpleFileWriter::request_context_ = NULL; | 22 URLRequestContext* SimpleFileWriter::request_context_ = NULL; |
| 23 | 23 |
| 24 // Helper class to proxy to write and truncate calls to the IO thread, | 24 // Helper class to proxy to write and truncate calls to the IO thread, |
| 25 // and to proxy the results back to the main thead. There is a one-to-one | 25 // and to proxy the results back to the main thead. There is a one-to-one |
| 26 // relationship between SimpleFileWriters and IOThreadBackends. | 26 // relationship between SimpleFileWriters and IOThreadBackends. |
| 27 class SimpleFileWriter::IOThreadProxy | 27 class SimpleFileWriter::IOThreadProxy |
| 28 : public base::RefCountedThreadSafe<SimpleFileWriter::IOThreadProxy> { | 28 : public base::RefCountedThreadSafe<SimpleFileWriter::IOThreadProxy> { |
| 29 public: | 29 public: |
| 30 explicit IOThreadProxy(const base::WeakPtr<SimpleFileWriter>& simple_writer) | 30 explicit IOThreadProxy(const base::WeakPtr<SimpleFileWriter>& simple_writer) |
| 31 : simple_writer_(simple_writer) { | 31 : simple_writer_(simple_writer), |
| 32 operation_(NULL) { |
| 32 // The IO thread needs to be running for this class to work. | 33 // The IO thread needs to be running for this class to work. |
| 33 SimpleResourceLoaderBridge::EnsureIOThread(); | 34 SimpleResourceLoaderBridge::EnsureIOThread(); |
| 34 io_thread_ = SimpleResourceLoaderBridge::GetIoThread(); | 35 io_thread_ = SimpleResourceLoaderBridge::GetIoThread(); |
| 35 main_thread_ = base::MessageLoopProxy::CreateForCurrentThread(); | 36 main_thread_ = base::MessageLoopProxy::CreateForCurrentThread(); |
| 36 } | 37 } |
| 37 | 38 |
| 38 virtual ~IOThreadProxy() { | 39 virtual ~IOThreadProxy() { |
| 39 } | 40 } |
| 40 | 41 |
| 41 void Truncate(const FilePath& path, int64 offset) { | 42 void Truncate(const FilePath& path, int64 offset) { |
| 42 if (!io_thread_->BelongsToCurrentThread()) { | 43 if (!io_thread_->BelongsToCurrentThread()) { |
| 43 io_thread_->PostTask(FROM_HERE, NewRunnableMethod( | 44 io_thread_->PostTask(FROM_HERE, NewRunnableMethod( |
| 44 this, &IOThreadProxy::Truncate, path, offset)); | 45 this, &IOThreadProxy::Truncate, path, offset)); |
| 45 return; | 46 return; |
| 46 } | 47 } |
| 47 DCHECK(!operation_.get()); | 48 DCHECK(!operation_); |
| 48 operation_.reset(GetNewOperation()); | 49 operation_ = GetNewOperation(); |
| 49 operation_->Truncate(path, offset); | 50 operation_->Truncate(path, offset); |
| 50 } | 51 } |
| 51 | 52 |
| 52 void Write(const FilePath& path, const GURL& blob_url, int64 offset) { | 53 void Write(const FilePath& path, const GURL& blob_url, int64 offset) { |
| 53 if (!io_thread_->BelongsToCurrentThread()) { | 54 if (!io_thread_->BelongsToCurrentThread()) { |
| 54 io_thread_->PostTask(FROM_HERE, NewRunnableMethod( | 55 io_thread_->PostTask(FROM_HERE, NewRunnableMethod( |
| 55 this, &IOThreadProxy::Write, path, blob_url, offset)); | 56 this, &IOThreadProxy::Write, path, blob_url, offset)); |
| 56 return; | 57 return; |
| 57 } | 58 } |
| 58 DCHECK(request_context_); | 59 DCHECK(request_context_); |
| 59 DCHECK(!operation_.get()); | 60 DCHECK(!operation_); |
| 60 operation_.reset(GetNewOperation()); | 61 operation_ = GetNewOperation(); |
| 61 operation_->Write(request_context_, path, blob_url, offset); | 62 operation_->Write(request_context_, path, blob_url, offset); |
| 62 } | 63 } |
| 63 | 64 |
| 64 void Cancel() { | 65 void Cancel() { |
| 65 if (!io_thread_->BelongsToCurrentThread()) { | 66 if (!io_thread_->BelongsToCurrentThread()) { |
| 66 io_thread_->PostTask(FROM_HERE, NewRunnableMethod( | 67 io_thread_->PostTask(FROM_HERE, NewRunnableMethod( |
| 67 this, &IOThreadProxy::Cancel)); | 68 this, &IOThreadProxy::Cancel)); |
| 68 return; | 69 return; |
| 69 } | 70 } |
| 70 if (!operation_.get()) { | 71 if (!operation_) { |
| 71 DidFail(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); | 72 DidFail(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
| 72 return; | 73 return; |
| 73 } | 74 } |
| 74 cancel_operation_.reset(GetNewOperation()); | 75 operation_->Cancel(GetNewOperation()); |
| 75 operation_->Cancel(cancel_operation_.get()); | |
| 76 } | 76 } |
| 77 | 77 |
| 78 private: | 78 private: |
| 79 // Inner class to receive callbacks from FileSystemOperation. | 79 // Inner class to receive callbacks from FileSystemOperation. |
| 80 class CallbackDispatcher : public FileSystemCallbackDispatcher { | 80 class CallbackDispatcher : public FileSystemCallbackDispatcher { |
| 81 public: | 81 public: |
| 82 explicit CallbackDispatcher(IOThreadProxy* proxy) : proxy_(proxy) { | 82 explicit CallbackDispatcher(IOThreadProxy* proxy) : proxy_(proxy) { |
| 83 } | 83 } |
| 84 | 84 |
| 85 ~CallbackDispatcher() { |
| 86 proxy_->ClearOperation(); |
| 87 } |
| 88 |
| 85 virtual void DidSucceed() { | 89 virtual void DidSucceed() { |
| 86 proxy_->DidSucceed(); | 90 proxy_->DidSucceed(); |
| 87 } | 91 } |
| 88 | 92 |
| 89 virtual void DidFail(base::PlatformFileError error_code) { | 93 virtual void DidFail(base::PlatformFileError error_code) { |
| 90 proxy_->DidFail(error_code); | 94 proxy_->DidFail(error_code); |
| 91 } | 95 } |
| 92 | 96 |
| 93 virtual void DidWrite(int64 bytes, bool complete) { | 97 virtual void DidWrite(int64 bytes, bool complete) { |
| 94 proxy_->DidWrite(bytes, complete); | 98 proxy_->DidWrite(bytes, complete); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 112 scoped_refptr<IOThreadProxy> proxy_; | 116 scoped_refptr<IOThreadProxy> proxy_; |
| 113 }; | 117 }; |
| 114 | 118 |
| 115 FileSystemOperation* GetNewOperation() { | 119 FileSystemOperation* GetNewOperation() { |
| 116 // The FileSystemOperation takes ownership of the CallbackDispatcher. | 120 // The FileSystemOperation takes ownership of the CallbackDispatcher. |
| 117 return new FileSystemOperation(new CallbackDispatcher(this), io_thread_); | 121 return new FileSystemOperation(new CallbackDispatcher(this), io_thread_); |
| 118 } | 122 } |
| 119 | 123 |
| 120 void DidSucceed() { | 124 void DidSucceed() { |
| 121 if (!main_thread_->BelongsToCurrentThread()) { | 125 if (!main_thread_->BelongsToCurrentThread()) { |
| 122 operation_.reset(); | |
| 123 main_thread_->PostTask(FROM_HERE, NewRunnableMethod( | 126 main_thread_->PostTask(FROM_HERE, NewRunnableMethod( |
| 124 this, &IOThreadProxy::DidSucceed)); | 127 this, &IOThreadProxy::DidSucceed)); |
| 125 return; | 128 return; |
| 126 } | 129 } |
| 127 if (simple_writer_) | 130 if (simple_writer_) |
| 128 simple_writer_->DidSucceed(); | 131 simple_writer_->DidSucceed(); |
| 129 } | 132 } |
| 130 | 133 |
| 131 void DidFail(base::PlatformFileError error_code) { | 134 void DidFail(base::PlatformFileError error_code) { |
| 132 if (!main_thread_->BelongsToCurrentThread()) { | 135 if (!main_thread_->BelongsToCurrentThread()) { |
| 133 operation_.reset(); | |
| 134 main_thread_->PostTask(FROM_HERE, NewRunnableMethod( | 136 main_thread_->PostTask(FROM_HERE, NewRunnableMethod( |
| 135 this, &IOThreadProxy::DidFail, error_code)); | 137 this, &IOThreadProxy::DidFail, error_code)); |
| 136 return; | 138 return; |
| 137 } | 139 } |
| 138 if (simple_writer_) | 140 if (simple_writer_) |
| 139 simple_writer_->DidFail(error_code); | 141 simple_writer_->DidFail(error_code); |
| 140 } | 142 } |
| 141 | 143 |
| 142 void DidWrite(int64 bytes, bool complete) { | 144 void DidWrite(int64 bytes, bool complete) { |
| 143 if (!main_thread_->BelongsToCurrentThread()) { | 145 if (!main_thread_->BelongsToCurrentThread()) { |
| 144 if (complete) | |
| 145 operation_.reset(); | |
| 146 main_thread_->PostTask(FROM_HERE, NewRunnableMethod( | 146 main_thread_->PostTask(FROM_HERE, NewRunnableMethod( |
| 147 this, &IOThreadProxy::DidWrite, bytes, complete)); | 147 this, &IOThreadProxy::DidWrite, bytes, complete)); |
| 148 return; | 148 return; |
| 149 } | 149 } |
| 150 if (simple_writer_) | 150 if (simple_writer_) |
| 151 simple_writer_->DidWrite(bytes, complete); | 151 simple_writer_->DidWrite(bytes, complete); |
| 152 } | 152 } |
| 153 | 153 |
| 154 void ClearOperation() { |
| 155 operation_ = NULL; |
| 156 } |
| 157 |
| 154 scoped_refptr<base::MessageLoopProxy> io_thread_; | 158 scoped_refptr<base::MessageLoopProxy> io_thread_; |
| 155 scoped_refptr<base::MessageLoopProxy> main_thread_; | 159 scoped_refptr<base::MessageLoopProxy> main_thread_; |
| 156 | 160 |
| 157 // Only used on the main thread. | 161 // Only used on the main thread. |
| 158 base::WeakPtr<SimpleFileWriter> simple_writer_; | 162 base::WeakPtr<SimpleFileWriter> simple_writer_; |
| 159 | 163 |
| 160 // Only used on the io thread. | 164 // Only used on the io thread. |
| 161 scoped_ptr<FileSystemOperation> operation_; | 165 FileSystemOperation* operation_; |
| 162 scoped_ptr<FileSystemOperation> cancel_operation_; | |
| 163 }; | 166 }; |
| 164 | 167 |
| 165 | 168 |
| 166 SimpleFileWriter::SimpleFileWriter( | 169 SimpleFileWriter::SimpleFileWriter( |
| 167 const WebString& path, WebFileWriterClient* client) | 170 const WebString& path, WebFileWriterClient* client) |
| 168 : WebFileWriterBase(path, client), | 171 : WebFileWriterBase(path, client), |
| 169 io_thread_proxy_(new IOThreadProxy(AsWeakPtr())) { | 172 io_thread_proxy_(new IOThreadProxy(AsWeakPtr())) { |
| 170 } | 173 } |
| 171 | 174 |
| 172 SimpleFileWriter::~SimpleFileWriter() { | 175 SimpleFileWriter::~SimpleFileWriter() { |
| 173 } | 176 } |
| 174 | 177 |
| 175 void SimpleFileWriter::DoTruncate(const FilePath& path, int64 offset) { | 178 void SimpleFileWriter::DoTruncate(const FilePath& path, int64 offset) { |
| 176 io_thread_proxy_->Truncate(path, offset); | 179 io_thread_proxy_->Truncate(path, offset); |
| 177 } | 180 } |
| 178 | 181 |
| 179 void SimpleFileWriter::DoWrite( | 182 void SimpleFileWriter::DoWrite( |
| 180 const FilePath& path, const GURL& blob_url, int64 offset) { | 183 const FilePath& path, const GURL& blob_url, int64 offset) { |
| 181 io_thread_proxy_->Write(path, blob_url, offset); | 184 io_thread_proxy_->Write(path, blob_url, offset); |
| 182 } | 185 } |
| 183 | 186 |
| 184 void SimpleFileWriter::DoCancel() { | 187 void SimpleFileWriter::DoCancel() { |
| 185 io_thread_proxy_->Cancel(); | 188 io_thread_proxy_->Cancel(); |
| 186 } | 189 } |
| OLD | NEW |