| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
| 11 | 11 |
| 12 namespace base { | 12 namespace base { |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 // Helper templates to call file_util or base::PlatformFile methods | 16 // Helper templates to call file_util or base::PlatformFile methods |
| 17 // and reply with the returned value. | 17 // and reply with the returned value. |
| 18 // | 18 // |
| 19 // Typically when you have these methods: | 19 // Typically when you have these methods: |
| 20 // R DoWorkAndReturn(); | 20 // R DoWorkAndReturn(); |
| 21 // void Callback(R& result); | 21 // void Callback(R& result); |
| 22 // | 22 // |
| 23 // You can pass the result of DoWorkAndReturn to the Callback by: | 23 // You can pass the result of DoWorkAndReturn to the Callback by: |
| 24 // | 24 // |
| 25 // R* result = new R; | 25 // R* result = new R; |
| 26 // message_loop_proxy->PostTaskAndReply( | 26 // message_loop_proxy->PostTaskAndReply( |
| 27 // from_here, | 27 // from_here, |
| 28 // ReturnAsParam<R>(Bind(&DoWorkAndReturn), result), | 28 // ReturnAsParam<R>(Bind(&DoWorkAndReturn), result), |
| 29 // CallbackWithReturn(Bind(&Callback), Owned(result))); | 29 // RelayHelper(Bind(&Callback), Owned(result))); |
| 30 // | 30 // |
| 31 // Or just use PostTaskAndReplyWithStatus helper template (see the code below). | 31 // Or just use PostTaskAndReplyWithStatus helper template (see the code below). |
| 32 template <typename R1, typename R2> | 32 template <typename R1, typename R2> |
| 33 struct ReturnValueTranslator { | 33 struct ReturnValueTranslator { |
| 34 static R2 Value(const R1& value); | 34 static R2 Value(const R1& value); |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 template <typename R> | 37 template <typename R> |
| 38 struct ReturnValueTranslator<R, R> { | 38 struct ReturnValueTranslator<R, R> { |
| 39 static R Value(const R& value) { return value; } | 39 static R Value(const R& value) { return value; } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 53 if (!func.is_null()) | 53 if (!func.is_null()) |
| 54 *result = ReturnValueTranslator<R1, R2>::Value(func.Run()); | 54 *result = ReturnValueTranslator<R1, R2>::Value(func.Run()); |
| 55 } | 55 } |
| 56 | 56 |
| 57 template <typename R1, typename R2> | 57 template <typename R1, typename R2> |
| 58 Closure ReturnAsParam(const Callback<R1(void)>& func, R2* result) { | 58 Closure ReturnAsParam(const Callback<R1(void)>& func, R2* result) { |
| 59 DCHECK(result); | 59 DCHECK(result); |
| 60 return Bind(&ReturnAsParamAdapter<R1, R2>, func, result); | 60 return Bind(&ReturnAsParamAdapter<R1, R2>, func, result); |
| 61 } | 61 } |
| 62 | 62 |
| 63 template <typename R, typename A1> |
| 64 void ReturnAsParamAdapter1(const Callback<R(A1)>& func, A1 a1, R* result) { |
| 65 if (!func.is_null()) |
| 66 *result = func.Run(a1); |
| 67 } |
| 68 |
| 69 template <typename R, typename A1> |
| 70 Closure ReturnAsParam(const Callback<R(A1)>& func, A1 a1, R* result) { |
| 71 DCHECK(result); |
| 72 return Bind(&ReturnAsParamAdapter1<R, A1>, func, a1, result); |
| 73 } |
| 74 |
| 63 template <typename R> | 75 template <typename R> |
| 64 void ReplyAdapter(const Callback<void(R)>& callback, R* result) { | 76 void ReplyAdapter(const Callback<void(R)>& callback, R* result) { |
| 65 DCHECK(result); | 77 DCHECK(result); |
| 66 if (!callback.is_null()) | 78 if (!callback.is_null()) |
| 67 callback.Run(*result); | 79 callback.Run(*result); |
| 68 } | 80 } |
| 69 | 81 |
| 70 template <typename R, typename OWNED> | 82 template <typename R, typename OWNED> |
| 71 Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) { | 83 Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) { |
| 72 return Bind(&ReplyAdapter<R>, callback, result); | 84 return Bind(&ReplyAdapter<R>, callback, result); |
| 73 } | 85 } |
| 74 | 86 |
| 75 // Putting everything together. | 87 // Putting everything together. |
| 76 template <typename R1, typename R2> | 88 template <typename R1, typename R2> |
| 77 bool PostTaskAndReplyWithStatus( | 89 bool PostTaskAndReplyWithStatus( |
| 78 const scoped_refptr<MessageLoopProxy>& message_loop_proxy, | 90 const scoped_refptr<MessageLoopProxy>& message_loop_proxy, |
| 79 const tracked_objects::Location& from_here, | 91 const tracked_objects::Location& from_here, |
| 80 const Callback<R1(void)>& file_util_work, | 92 const Callback<R1(void)>& file_util_work, |
| 81 const Callback<void(R2)>& callback, | 93 const Callback<void(R2)>& callback, |
| 82 R2* result) { | 94 R2* result) { |
| 83 return message_loop_proxy->PostTaskAndReply( | 95 return message_loop_proxy->PostTaskAndReply( |
| 84 from_here, | 96 from_here, |
| 85 ReturnAsParam<R1>(file_util_work, result), | 97 ReturnAsParam<R1>(file_util_work, result), |
| 86 ReplyHelper(callback, Owned(result))); | 98 ReplyHelper(callback, Owned(result))); |
| 87 } | 99 } |
| 88 | 100 |
| 89 // Helper classes or routines for individual methods. | 101 // Helper classes or routines for individual methods. |
| 90 class CreateOrOpenHelper { | 102 class CreateOrOpenHelper { |
| 91 public: | 103 public: |
| 92 CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy) | 104 CreateOrOpenHelper(MessageLoopProxy* message_loop_proxy, |
| 105 const FileUtilProxy::CloseTask& close_task) |
| 93 : message_loop_proxy_(message_loop_proxy), | 106 : message_loop_proxy_(message_loop_proxy), |
| 107 close_task_(close_task), |
| 94 file_handle_(kInvalidPlatformFileValue), | 108 file_handle_(kInvalidPlatformFileValue), |
| 95 created_(false), | 109 created_(false), |
| 96 error_(PLATFORM_FILE_OK) {} | 110 error_(PLATFORM_FILE_OK) {} |
| 97 | 111 |
| 98 ~CreateOrOpenHelper() { | 112 ~CreateOrOpenHelper() { |
| 99 if (file_handle_ != kInvalidPlatformFileValue) { | 113 if (file_handle_ != kInvalidPlatformFileValue) { |
| 100 FileUtilProxy::Close(message_loop_proxy_, file_handle_, | 114 message_loop_proxy_->PostTask( |
| 101 FileUtilProxy::StatusCallback()); | 115 FROM_HERE, base::Bind(close_task_, file_handle_)); |
| 102 } | 116 } |
| 103 } | 117 } |
| 104 | 118 |
| 105 void RunWork(const FilePath& file_path, int file_flags) { | 119 void RunWork(const FileUtilProxy::CreateOrOpenTask& task) { |
| 106 if (!file_util::DirectoryExists(file_path.DirName())) { | 120 error_ = task.Run(&file_handle_, &created_); |
| 107 // If its parent does not exist, should return NOT_FOUND error. | |
| 108 error_ = PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 109 return; | |
| 110 } | |
| 111 error_ = PLATFORM_FILE_OK; | |
| 112 file_handle_ = CreatePlatformFile(file_path, file_flags, | |
| 113 &created_, &error_); | |
| 114 } | 121 } |
| 115 | 122 |
| 116 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) { | 123 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) { |
| 117 DCHECK(!callback.is_null()); | 124 DCHECK(!callback.is_null()); |
| 118 callback.Run(error_, PassPlatformFile(&file_handle_), created_); | 125 callback.Run(error_, PassPlatformFile(&file_handle_), created_); |
| 119 } | 126 } |
| 120 | 127 |
| 121 private: | 128 private: |
| 122 scoped_refptr<MessageLoopProxy> message_loop_proxy_; | 129 scoped_refptr<MessageLoopProxy> message_loop_proxy_; |
| 130 FileUtilProxy::CloseTask close_task_; |
| 123 PlatformFile file_handle_; | 131 PlatformFile file_handle_; |
| 124 bool created_; | 132 bool created_; |
| 125 PlatformFileError error_; | 133 PlatformFileError error_; |
| 126 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper); | 134 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper); |
| 127 }; | 135 }; |
| 128 | 136 |
| 129 class CreateTemporaryHelper { | 137 class CreateTemporaryHelper { |
| 130 public: | 138 public: |
| 131 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy) | 139 CreateTemporaryHelper(MessageLoopProxy* message_loop_proxy) |
| 132 : message_loop_proxy_(message_loop_proxy), | 140 : message_loop_proxy_(message_loop_proxy), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 161 } | 169 } |
| 162 | 170 |
| 163 private: | 171 private: |
| 164 scoped_refptr<MessageLoopProxy> message_loop_proxy_; | 172 scoped_refptr<MessageLoopProxy> message_loop_proxy_; |
| 165 PlatformFile file_handle_; | 173 PlatformFile file_handle_; |
| 166 FilePath file_path_; | 174 FilePath file_path_; |
| 167 PlatformFileError error_; | 175 PlatformFileError error_; |
| 168 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper); | 176 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper); |
| 169 }; | 177 }; |
| 170 | 178 |
| 171 PlatformFileError DeleteHelper(const FilePath& file_path, bool recursive) { | |
| 172 if (!file_util::PathExists(file_path)) { | |
| 173 return PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 174 } | |
| 175 if (!file_util::Delete(file_path, recursive)) { | |
| 176 if (!recursive && !file_util::IsDirectoryEmpty(file_path)) { | |
| 177 return PLATFORM_FILE_ERROR_NOT_EMPTY; | |
| 178 } | |
| 179 return PLATFORM_FILE_ERROR_FAILED; | |
| 180 } | |
| 181 return PLATFORM_FILE_OK; | |
| 182 } | |
| 183 | |
| 184 class GetFileInfoHelper { | 179 class GetFileInfoHelper { |
| 185 public: | 180 public: |
| 186 GetFileInfoHelper() | 181 GetFileInfoHelper() |
| 187 : error_(PLATFORM_FILE_OK) {} | 182 : error_(PLATFORM_FILE_OK) {} |
| 188 | 183 |
| 189 void RunWorkForFilePath(const FilePath& file_path) { | 184 void RunWorkForFilePath(const FilePath& file_path) { |
| 190 if (!file_util::PathExists(file_path)) { | 185 if (!file_util::PathExists(file_path)) { |
| 191 error_ = PLATFORM_FILE_ERROR_NOT_FOUND; | 186 error_ = PLATFORM_FILE_ERROR_NOT_FOUND; |
| 192 return; | 187 return; |
| 193 } | 188 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 255 } |
| 261 } | 256 } |
| 262 | 257 |
| 263 private: | 258 private: |
| 264 scoped_array<char> buffer_; | 259 scoped_array<char> buffer_; |
| 265 int bytes_to_write_; | 260 int bytes_to_write_; |
| 266 int bytes_written_; | 261 int bytes_written_; |
| 267 DISALLOW_COPY_AND_ASSIGN(WriteHelper); | 262 DISALLOW_COPY_AND_ASSIGN(WriteHelper); |
| 268 }; | 263 }; |
| 269 | 264 |
| 265 |
| 266 PlatformFileError CreateOrOpenAdapter( |
| 267 const FilePath& file_path, int file_flags, |
| 268 PlatformFile* file_handle, bool* created) { |
| 269 DCHECK(file_handle); |
| 270 DCHECK(created); |
| 271 if (!file_util::DirectoryExists(file_path.DirName())) { |
| 272 // If its parent does not exist, should return NOT_FOUND error. |
| 273 return PLATFORM_FILE_ERROR_NOT_FOUND; |
| 274 } |
| 275 PlatformFileError error = PLATFORM_FILE_OK; |
| 276 *file_handle = CreatePlatformFile(file_path, file_flags, created, &error); |
| 277 return error; |
| 278 } |
| 279 |
| 280 PlatformFileError CloseAdapter(PlatformFile file_handle) { |
| 281 if (!ClosePlatformFile(file_handle)) { |
| 282 return PLATFORM_FILE_ERROR_FAILED; |
| 283 } |
| 284 return PLATFORM_FILE_OK; |
| 285 } |
| 286 |
| 287 PlatformFileError DeleteAdapter(const FilePath& file_path, bool recursive) { |
| 288 if (!file_util::PathExists(file_path)) { |
| 289 return PLATFORM_FILE_ERROR_NOT_FOUND; |
| 290 } |
| 291 if (!file_util::Delete(file_path, recursive)) { |
| 292 if (!recursive && !file_util::IsDirectoryEmpty(file_path)) { |
| 293 return PLATFORM_FILE_ERROR_NOT_EMPTY; |
| 294 } |
| 295 return PLATFORM_FILE_ERROR_FAILED; |
| 296 } |
| 297 return PLATFORM_FILE_OK; |
| 298 } |
| 299 |
| 270 } // namespace | 300 } // namespace |
| 271 | 301 |
| 272 // static | 302 // static |
| 273 bool FileUtilProxy::CreateOrOpen( | 303 bool FileUtilProxy::CreateOrOpen( |
| 274 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 304 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 275 const FilePath& file_path, int file_flags, | 305 const FilePath& file_path, int file_flags, |
| 276 const CreateOrOpenCallback& callback) { | 306 const CreateOrOpenCallback& callback) { |
| 277 CreateOrOpenHelper* helper = new CreateOrOpenHelper(message_loop_proxy); | 307 return RelayCreateOrOpen( |
| 278 return message_loop_proxy->PostTaskAndReply( | 308 message_loop_proxy, |
| 279 FROM_HERE, | 309 base::Bind(&CreateOrOpenAdapter, file_path, file_flags), |
| 280 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), | 310 base::Bind(&CloseAdapter), |
| 281 file_path, file_flags), | 311 callback); |
| 282 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback)); | |
| 283 } | 312 } |
| 284 | 313 |
| 285 // static | 314 // static |
| 286 bool FileUtilProxy::CreateTemporary( | 315 bool FileUtilProxy::CreateTemporary( |
| 287 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 316 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 288 int additional_file_flags, | 317 int additional_file_flags, |
| 289 const CreateTemporaryCallback& callback) { | 318 const CreateTemporaryCallback& callback) { |
| 290 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy); | 319 CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy); |
| 291 return message_loop_proxy->PostTaskAndReply( | 320 return message_loop_proxy->PostTaskAndReply( |
| 292 FROM_HERE, | 321 FROM_HERE, |
| 293 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), | 322 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper), |
| 294 additional_file_flags), | 323 additional_file_flags), |
| 295 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); | 324 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback)); |
| 296 } | 325 } |
| 297 | 326 |
| 298 // static | 327 // static |
| 299 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 328 bool FileUtilProxy::Close( |
| 300 PlatformFile file_handle, | 329 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 301 const StatusCallback& callback) { | 330 base::PlatformFile file_handle, |
| 302 return PostTaskAndReplyWithStatus<bool>( | 331 const StatusCallback& callback) { |
| 303 message_loop_proxy, FROM_HERE, | 332 return RelayClose( |
| 304 Bind(&ClosePlatformFile, file_handle), callback, | 333 message_loop_proxy, |
| 305 new PlatformFileError); | 334 base::Bind(&CloseAdapter), |
| 335 file_handle, callback); |
| 306 } | 336 } |
| 307 | 337 |
| 308 // Retrieves the information about a file. It is invalid to pass NULL for the | 338 // Retrieves the information about a file. It is invalid to pass NULL for the |
| 309 // callback. | 339 // callback. |
| 310 bool FileUtilProxy::GetFileInfo( | 340 bool FileUtilProxy::GetFileInfo( |
| 311 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 341 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 312 const FilePath& file_path, | 342 const FilePath& file_path, |
| 313 const GetFileInfoCallback& callback) { | 343 const GetFileInfoCallback& callback) { |
| 314 GetFileInfoHelper* helper = new GetFileInfoHelper; | 344 GetFileInfoHelper* helper = new GetFileInfoHelper; |
| 315 return message_loop_proxy->PostTaskAndReply( | 345 return message_loop_proxy->PostTaskAndReply( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 330 Bind(&GetFileInfoHelper::RunWorkForPlatformFile, | 360 Bind(&GetFileInfoHelper::RunWorkForPlatformFile, |
| 331 Unretained(helper), file), | 361 Unretained(helper), file), |
| 332 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); | 362 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback)); |
| 333 } | 363 } |
| 334 | 364 |
| 335 // static | 365 // static |
| 336 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 366 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 337 const FilePath& file_path, | 367 const FilePath& file_path, |
| 338 bool recursive, | 368 bool recursive, |
| 339 const StatusCallback& callback) { | 369 const StatusCallback& callback) { |
| 340 return PostTaskAndReplyWithStatus<PlatformFileError>( | 370 return RelayFileTask( |
| 341 message_loop_proxy, FROM_HERE, | 371 message_loop_proxy, FROM_HERE, |
| 342 Bind(&DeleteHelper, file_path, recursive), callback, | 372 Bind(&DeleteAdapter, file_path, recursive), |
| 343 new PlatformFileError); | 373 callback); |
| 344 } | 374 } |
| 345 | 375 |
| 346 // static | 376 // static |
| 347 bool FileUtilProxy::RecursiveDelete( | 377 bool FileUtilProxy::RecursiveDelete( |
| 348 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 378 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 349 const FilePath& file_path, | 379 const FilePath& file_path, |
| 350 const StatusCallback& callback) { | 380 const StatusCallback& callback) { |
| 351 return PostTaskAndReplyWithStatus<PlatformFileError>( | 381 return RelayFileTask( |
| 352 message_loop_proxy, FROM_HERE, | 382 message_loop_proxy, FROM_HERE, |
| 353 Bind(&DeleteHelper, file_path, true /* recursive */), callback, | 383 Bind(&DeleteAdapter, file_path, true /* recursive */), |
| 354 new PlatformFileError); | 384 callback); |
| 355 } | 385 } |
| 356 | 386 |
| 357 // static | 387 // static |
| 358 bool FileUtilProxy::Read( | 388 bool FileUtilProxy::Read( |
| 359 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 389 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 360 PlatformFile file, | 390 PlatformFile file, |
| 361 int64 offset, | 391 int64 offset, |
| 362 int bytes_to_read, | 392 int bytes_to_read, |
| 363 const ReadCallback& callback) { | 393 const ReadCallback& callback) { |
| 364 if (bytes_to_read < 0) { | 394 if (bytes_to_read < 0) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 bool FileUtilProxy::Flush( | 464 bool FileUtilProxy::Flush( |
| 435 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 465 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 436 PlatformFile file, | 466 PlatformFile file, |
| 437 const StatusCallback& callback) { | 467 const StatusCallback& callback) { |
| 438 return PostTaskAndReplyWithStatus<bool>( | 468 return PostTaskAndReplyWithStatus<bool>( |
| 439 message_loop_proxy, FROM_HERE, | 469 message_loop_proxy, FROM_HERE, |
| 440 Bind(&FlushPlatformFile, file), callback, | 470 Bind(&FlushPlatformFile, file), callback, |
| 441 new PlatformFileError); | 471 new PlatformFileError); |
| 442 } | 472 } |
| 443 | 473 |
| 474 // static |
| 475 bool FileUtilProxy::RelayFileTask( |
| 476 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 477 const tracked_objects::Location& from_here, |
| 478 const FileTask& file_task, |
| 479 const StatusCallback& callback) { |
| 480 PlatformFileError* result = new PlatformFileError; |
| 481 return message_loop_proxy->PostTaskAndReply( |
| 482 from_here, |
| 483 ReturnAsParam(file_task, result), |
| 484 ReplyHelper(callback, Owned(result))); |
| 485 } |
| 486 |
| 487 // static |
| 488 bool FileUtilProxy::RelayCreateOrOpen( |
| 489 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 490 const CreateOrOpenTask& open_task, |
| 491 const CloseTask& close_task, |
| 492 const CreateOrOpenCallback& callback) { |
| 493 CreateOrOpenHelper* helper = new CreateOrOpenHelper( |
| 494 message_loop_proxy, close_task); |
| 495 return message_loop_proxy->PostTaskAndReply( |
| 496 FROM_HERE, |
| 497 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task), |
| 498 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback)); |
| 499 } |
| 500 |
| 501 // static |
| 502 bool FileUtilProxy::RelayClose( |
| 503 scoped_refptr<MessageLoopProxy> message_loop_proxy, |
| 504 const CloseTask& close_task, |
| 505 PlatformFile file_handle, |
| 506 const StatusCallback& callback) { |
| 507 PlatformFileError* result = new PlatformFileError; |
| 508 return message_loop_proxy->PostTaskAndReply( |
| 509 FROM_HERE, |
| 510 ReturnAsParam(close_task, file_handle, result), |
| 511 ReplyHelper(callback, Owned(result))); |
| 512 } |
| 513 |
| 444 } // namespace base | 514 } // namespace base |
| OLD | NEW |