Chromium Code Reviews| 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 "base/file_util_proxy.h" | 5 #include "base/file_util_proxy.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
| 9 | 9 |
| 10 namespace { | 10 namespace { |
| 11 | 11 |
| 12 class MessageLoopRelay | 12 class MessageLoopRelay |
| 13 : public base::RefCountedThreadSafe<MessageLoopRelay> { | 13 : public base::RefCountedThreadSafe<MessageLoopRelay> { |
| 14 public: | 14 public: |
| 15 MessageLoopRelay() | 15 MessageLoopRelay() |
| 16 : origin_message_loop_proxy_( | 16 : origin_message_loop_proxy_( |
| 17 base::MessageLoopProxy::CreateForCurrentThread()) { | 17 base::MessageLoopProxy::CreateForCurrentThread()), |
| 18 error_code_(base::PLATFORM_FILE_OK) { | |
| 18 } | 19 } |
| 19 | 20 |
| 20 void Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 21 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 21 const tracked_objects::Location& from_here) { | 22 const tracked_objects::Location& from_here) { |
| 22 message_loop_proxy->PostTask( | 23 return message_loop_proxy->PostTask( |
| 23 from_here, | 24 from_here, |
| 24 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); | 25 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); |
| 25 } | 26 } |
| 26 | 27 |
| 27 protected: | 28 protected: |
| 28 friend class base::RefCountedThreadSafe<MessageLoopRelay>; | 29 friend class base::RefCountedThreadSafe<MessageLoopRelay>; |
| 29 virtual ~MessageLoopRelay() {} | 30 virtual ~MessageLoopRelay() {} |
| 30 | 31 |
| 31 // Called to perform work on the FILE thread. | 32 // Called to perform work on the FILE thread. |
| 32 virtual void RunWork() = 0; | 33 virtual void RunWork() = 0; |
| 33 | 34 |
| 34 // Called to notify the callback on the origin thread. | 35 // Called to notify the callback on the origin thread. |
| 35 virtual void RunCallback() = 0; | 36 virtual void RunCallback() = 0; |
| 36 | 37 |
| 38 void SetErrorCode(int error_code) { | |
| 39 error_code_ = error_code; | |
| 40 } | |
| 41 | |
| 42 int ErrorCode() { | |
|
darin (slow to review)
2010/08/24 17:43:14
nit: consider naming these set_error_code() and er
dumi
2010/08/24 19:14:57
done. when do we use methods_like_this() and Metho
| |
| 43 return error_code_; | |
| 44 } | |
| 45 | |
| 37 private: | 46 private: |
| 38 void ProcessOnTargetThread() { | 47 void ProcessOnTargetThread() { |
| 39 RunWork(); | 48 RunWork(); |
| 40 origin_message_loop_proxy_->PostTask( | 49 origin_message_loop_proxy_->PostTask( |
| 41 FROM_HERE, | 50 FROM_HERE, |
| 42 NewRunnableMethod(this, &MessageLoopRelay::RunCallback)); | 51 NewRunnableMethod(this, &MessageLoopRelay::RunCallback)); |
| 43 } | 52 } |
| 44 | 53 |
| 45 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | 54 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; |
| 55 int error_code_; | |
| 46 }; | 56 }; |
| 47 | 57 |
| 48 class RelayCreateOrOpen : public MessageLoopRelay { | 58 class RelayCreateOrOpen : public MessageLoopRelay { |
| 49 public: | 59 public: |
| 50 RelayCreateOrOpen( | 60 RelayCreateOrOpen( |
| 51 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 61 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 52 const FilePath& file_path, | 62 const FilePath& file_path, |
| 53 int file_flags, | 63 int file_flags, |
| 54 base::FileUtilProxy::CreateOrOpenCallback* callback) | 64 base::FileUtilProxy::CreateOrOpenCallback* callback) |
| 55 : message_loop_proxy_(message_loop_proxy), | 65 : message_loop_proxy_(message_loop_proxy), |
| 56 file_path_(file_path), | 66 file_path_(file_path), |
| 57 file_flags_(file_flags), | 67 file_flags_(file_flags), |
| 58 callback_(callback), | 68 callback_(callback), |
| 59 file_handle_(base::kInvalidPlatformFileValue), | 69 file_handle_(base::kInvalidPlatformFileValue), |
| 60 created_(false) { | 70 created_(false) { |
| 61 DCHECK(callback); | 71 DCHECK(callback); |
| 62 } | 72 } |
| 63 | 73 |
| 64 protected: | 74 protected: |
| 65 virtual ~RelayCreateOrOpen() { | 75 virtual ~RelayCreateOrOpen() { |
| 66 if (file_handle_ != base::kInvalidPlatformFileValue) | 76 if (file_handle_ != base::kInvalidPlatformFileValue) |
| 67 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); | 77 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); |
| 68 } | 78 } |
| 69 | 79 |
| 70 virtual void RunWork() { | 80 virtual void RunWork() { |
| 71 file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, &created_); | 81 file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, &created_); |
| 82 if (file_handle_ == base::kInvalidPlatformFileValue) | |
| 83 SetErrorCode(base::PLATFORM_FILE_ERROR); | |
| 72 } | 84 } |
| 73 | 85 |
| 74 virtual void RunCallback() { | 86 virtual void RunCallback() { |
| 75 callback_->Run(base::PassPlatformFile(&file_handle_), created_); | 87 callback_->Run(ErrorCode(), base::PassPlatformFile(&file_handle_), |
| 88 created_); | |
| 76 delete callback_; | 89 delete callback_; |
| 77 } | 90 } |
| 78 | 91 |
| 79 private: | 92 private: |
| 80 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | 93 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
| 81 FilePath file_path_; | 94 FilePath file_path_; |
| 82 int file_flags_; | 95 int file_flags_; |
| 83 base::FileUtilProxy::CreateOrOpenCallback* callback_; | 96 base::FileUtilProxy::CreateOrOpenCallback* callback_; |
| 84 base::PlatformFile file_handle_; | 97 base::PlatformFile file_handle_; |
| 85 bool created_; | 98 bool created_; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 108 file_util::CreateTemporaryFile(&file_path_); | 121 file_util::CreateTemporaryFile(&file_path_); |
| 109 | 122 |
| 110 // Use a fixed set of flags that are appropriate for writing to a temporary | 123 // Use a fixed set of flags that are appropriate for writing to a temporary |
| 111 // file from the IO thread using a net::FileStream. | 124 // file from the IO thread using a net::FileStream. |
| 112 int file_flags = | 125 int file_flags = |
| 113 base::PLATFORM_FILE_CREATE_ALWAYS | | 126 base::PLATFORM_FILE_CREATE_ALWAYS | |
| 114 base::PLATFORM_FILE_WRITE | | 127 base::PLATFORM_FILE_WRITE | |
| 115 base::PLATFORM_FILE_ASYNC | | 128 base::PLATFORM_FILE_ASYNC | |
| 116 base::PLATFORM_FILE_TEMPORARY; | 129 base::PLATFORM_FILE_TEMPORARY; |
| 117 file_handle_ = base::CreatePlatformFile(file_path_, file_flags, NULL); | 130 file_handle_ = base::CreatePlatformFile(file_path_, file_flags, NULL); |
| 131 if (file_handle_ == base::kInvalidPlatformFileValue) | |
| 132 SetErrorCode(base::PLATFORM_FILE_ERROR); | |
| 118 } | 133 } |
| 119 | 134 |
| 120 virtual void RunCallback() { | 135 virtual void RunCallback() { |
| 121 callback_->Run(base::PassPlatformFile(&file_handle_), file_path_); | 136 callback_->Run(ErrorCode(), base::PassPlatformFile(&file_handle_), |
| 137 file_path_); | |
| 122 delete callback_; | 138 delete callback_; |
| 123 } | 139 } |
| 124 | 140 |
| 125 private: | 141 private: |
| 126 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | 142 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
| 127 base::FileUtilProxy::CreateTemporaryCallback* callback_; | 143 base::FileUtilProxy::CreateTemporaryCallback* callback_; |
| 128 base::PlatformFile file_handle_; | 144 base::PlatformFile file_handle_; |
| 129 FilePath file_path_; | 145 FilePath file_path_; |
| 130 }; | 146 }; |
| 131 | 147 |
| 132 class RelayWithStatusCallback : public MessageLoopRelay { | 148 class RelayWithStatusCallback : public MessageLoopRelay { |
| 133 public: | 149 public: |
| 134 explicit RelayWithStatusCallback( | 150 explicit RelayWithStatusCallback( |
| 135 base::FileUtilProxy::StatusCallback* callback) | 151 base::FileUtilProxy::StatusCallback* callback) |
| 136 : callback_(callback), | 152 : callback_(callback) { |
| 137 succeeded_(false) { | |
| 138 // It is OK for callback to be NULL. | 153 // It is OK for callback to be NULL. |
| 139 } | 154 } |
| 140 | 155 |
| 141 protected: | 156 protected: |
| 142 virtual void RunCallback() { | 157 virtual void RunCallback() { |
| 143 // The caller may not have been interested in the result. | 158 // The caller may not have been interested in the result. |
| 144 if (callback_) { | 159 if (callback_) { |
| 145 callback_->Run(succeeded_); | 160 callback_->Run(ErrorCode()); |
| 146 delete callback_; | 161 delete callback_; |
| 147 } | 162 } |
| 148 } | 163 } |
| 149 | 164 |
| 150 void SetStatus(bool succeeded) { succeeded_ = succeeded; } | |
| 151 | |
| 152 private: | 165 private: |
| 153 base::FileUtilProxy::StatusCallback* callback_; | 166 base::FileUtilProxy::StatusCallback* callback_; |
| 154 bool succeeded_; | |
| 155 }; | 167 }; |
| 156 | 168 |
| 157 class RelayClose : public RelayWithStatusCallback { | 169 class RelayClose : public RelayWithStatusCallback { |
| 158 public: | 170 public: |
| 159 RelayClose(base::PlatformFile file_handle, | 171 RelayClose(base::PlatformFile file_handle, |
| 160 base::FileUtilProxy::StatusCallback* callback) | 172 base::FileUtilProxy::StatusCallback* callback) |
| 161 : RelayWithStatusCallback(callback), | 173 : RelayWithStatusCallback(callback), |
| 162 file_handle_(file_handle) { | 174 file_handle_(file_handle) { |
| 163 } | 175 } |
| 164 | 176 |
| 165 protected: | 177 protected: |
| 166 virtual void RunWork() { | 178 virtual void RunWork() { |
| 167 SetStatus(base::ClosePlatformFile(file_handle_)); | 179 if (!base::ClosePlatformFile(file_handle_)) |
| 180 SetErrorCode(base::PLATFORM_FILE_ERROR); | |
| 168 } | 181 } |
| 169 | 182 |
| 170 private: | 183 private: |
| 171 base::PlatformFile file_handle_; | 184 base::PlatformFile file_handle_; |
| 172 }; | 185 }; |
| 173 | 186 |
| 174 class RelayDelete : public RelayWithStatusCallback { | 187 class RelayDelete : public RelayWithStatusCallback { |
| 175 public: | 188 public: |
| 176 RelayDelete(const FilePath& file_path, | 189 RelayDelete(const FilePath& file_path, |
| 177 bool recursive, | 190 bool recursive, |
| 178 base::FileUtilProxy::StatusCallback* callback) | 191 base::FileUtilProxy::StatusCallback* callback) |
| 179 : RelayWithStatusCallback(callback), | 192 : RelayWithStatusCallback(callback), |
| 180 file_path_(file_path), | 193 file_path_(file_path), |
| 181 recursive_(recursive) { | 194 recursive_(recursive) { |
| 182 } | 195 } |
| 183 | 196 |
| 184 protected: | 197 protected: |
| 185 virtual void RunWork() { | 198 virtual void RunWork() { |
| 186 SetStatus(file_util::Delete(file_path_, recursive_)); | 199 if (!file_util::Delete(file_path_, recursive_)) |
| 200 SetErrorCode(base::PLATFORM_FILE_ERROR); | |
| 187 } | 201 } |
| 188 | 202 |
| 189 private: | 203 private: |
| 190 FilePath file_path_; | 204 FilePath file_path_; |
| 191 bool recursive_; | 205 bool recursive_; |
| 192 }; | 206 }; |
| 193 | 207 |
| 194 void Start(const tracked_objects::Location& from_here, | 208 bool Start(const tracked_objects::Location& from_here, |
| 195 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 209 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 196 scoped_refptr<MessageLoopRelay> relay) { | 210 scoped_refptr<MessageLoopRelay> relay) { |
| 197 relay->Start(message_loop_proxy, from_here); | 211 return relay->Start(message_loop_proxy, from_here); |
| 198 } | 212 } |
| 199 | 213 |
| 200 } // namespace | 214 } // namespace |
| 201 | 215 |
| 202 namespace base { | 216 namespace base { |
| 203 | 217 |
| 204 // static | 218 // static |
| 205 void FileUtilProxy::CreateOrOpen( | 219 bool FileUtilProxy::CreateOrOpen( |
| 206 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 220 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 207 const FilePath& file_path, int file_flags, | 221 const FilePath& file_path, int file_flags, |
| 208 CreateOrOpenCallback* callback) { | 222 CreateOrOpenCallback* callback) { |
| 209 Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen( | 223 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen( |
| 210 message_loop_proxy, file_path, file_flags, callback)); | 224 message_loop_proxy, file_path, file_flags, callback)); |
| 211 } | 225 } |
| 212 | 226 |
| 213 // static | 227 // static |
| 214 void FileUtilProxy::CreateTemporary( | 228 bool FileUtilProxy::CreateTemporary( |
| 215 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 229 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 216 CreateTemporaryCallback* callback) { | 230 CreateTemporaryCallback* callback) { |
| 217 Start(FROM_HERE, message_loop_proxy, | 231 return Start(FROM_HERE, message_loop_proxy, |
| 218 new RelayCreateTemporary(message_loop_proxy, callback)); | 232 new RelayCreateTemporary(message_loop_proxy, callback)); |
| 219 } | 233 } |
| 220 | 234 |
| 221 // static | 235 // static |
| 222 void FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 236 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 223 base::PlatformFile file_handle, | 237 base::PlatformFile file_handle, |
| 224 StatusCallback* callback) { | 238 StatusCallback* callback) { |
| 225 Start(FROM_HERE, message_loop_proxy, new RelayClose(file_handle, callback)); | 239 return Start(FROM_HERE, message_loop_proxy, |
| 240 new RelayClose(file_handle, callback)); | |
| 226 } | 241 } |
| 227 | 242 |
| 228 // static | 243 // static |
| 229 void FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 244 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 230 const FilePath& file_path, | 245 const FilePath& file_path, |
| 231 StatusCallback* callback) { | 246 StatusCallback* callback) { |
| 232 Start(FROM_HERE, message_loop_proxy, | 247 return Start(FROM_HERE, message_loop_proxy, |
| 233 new RelayDelete(file_path, false, callback)); | 248 new RelayDelete(file_path, false, callback)); |
| 234 } | 249 } |
| 235 | 250 |
| 236 // static | 251 // static |
| 237 void FileUtilProxy::RecursiveDelete( | 252 bool FileUtilProxy::RecursiveDelete( |
| 238 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 253 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 239 const FilePath& file_path, | 254 const FilePath& file_path, |
| 240 StatusCallback* callback) { | 255 StatusCallback* callback) { |
| 241 Start(FROM_HERE, message_loop_proxy, | 256 return Start(FROM_HERE, message_loop_proxy, |
| 242 new RelayDelete(file_path, true, callback)); | 257 new RelayDelete(file_path, true, callback)); |
| 243 } | 258 } |
| 244 | 259 |
| 245 } // namespace base | 260 } // namespace base |
| OLD | NEW |