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 |