Commit e3e1ca1e authored by tzik's avatar tzik Committed by Commit Bot

Avoid touching ScopedFileOpener::Runner's ref count before it's fully constructed

ScopedFileOpener::Runner is a ref counted object, and its first reference
used to be made in its constructor through base::Bind.
The reference is passed to ProvidedFileSystem::OpenFile, and released
when the callback object is destroyed.

However, if OpenFile failed, the reference is released before the
Runner construction has done. Then `new Runner` returns a stale pointer,
instead of newly created object.

This CL adds a static consntructor and moves the implicit ref count
manipulation out of the real constructor.

Bug: 866456
Change-Id: I92d68b3383d8fecd900be080cc23551cddb5f12b
Reviewed-on: https://chromium-review.googlesource.com/1156325Reviewed-by: default avatarTatsuhisa Yamaguchi <yamaguchi@chromium.org>
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579359}
parent c2a687a9
...@@ -17,18 +17,16 @@ using OpenFileCallback = ProvidedFileSystemInterface::OpenFileCallback; ...@@ -17,18 +17,16 @@ using OpenFileCallback = ProvidedFileSystemInterface::OpenFileCallback;
class ScopedFileOpener::Runner class ScopedFileOpener::Runner
: public base::RefCounted<ScopedFileOpener::Runner> { : public base::RefCounted<ScopedFileOpener::Runner> {
public: public:
Runner(ProvidedFileSystemInterface* file_system, static scoped_refptr<Runner> Create(ProvidedFileSystemInterface* file_system,
const base::FilePath& file_path, const base::FilePath& file_path,
OpenFileMode mode, OpenFileMode mode,
OpenFileCallback callback) OpenFileCallback callback) {
: file_system_(file_system->GetWeakPtr()), auto runner =
open_callback_(std::move(callback)), base::WrapRefCounted(new Runner(file_system, std::move(callback)));
aborting_requested_(false), runner->abort_callback_ = file_system->OpenFile(
open_completed_(false),
file_handle_(0) {
abort_callback_ = file_system_->OpenFile(
file_path, mode, file_path, mode,
base::Bind(&ScopedFileOpener::Runner::OnOpenFileCompleted, this)); base::Bind(&ScopedFileOpener::Runner::OnOpenFileCompleted, runner));
return runner;
} }
// Aborts pending open operation, or closes a file if it's already opened. // Aborts pending open operation, or closes a file if it's already opened.
...@@ -59,6 +57,13 @@ class ScopedFileOpener::Runner ...@@ -59,6 +57,13 @@ class ScopedFileOpener::Runner
private: private:
friend class base::RefCounted<ScopedFileOpener::Runner>; friend class base::RefCounted<ScopedFileOpener::Runner>;
Runner(ProvidedFileSystemInterface* file_system, OpenFileCallback callback)
: file_system_(file_system->GetWeakPtr()),
open_callback_(std::move(callback)),
aborting_requested_(false),
open_completed_(false),
file_handle_(0) {}
~Runner() {} ~Runner() {}
// Called when opening is completed with either a success or an error. // Called when opening is completed with either a success or an error.
...@@ -127,7 +132,8 @@ ScopedFileOpener::ScopedFileOpener(ProvidedFileSystemInterface* file_system, ...@@ -127,7 +132,8 @@ ScopedFileOpener::ScopedFileOpener(ProvidedFileSystemInterface* file_system,
const base::FilePath& file_path, const base::FilePath& file_path,
OpenFileMode mode, OpenFileMode mode,
OpenFileCallback callback) OpenFileCallback callback)
: runner_(new Runner(file_system, file_path, mode, std::move(callback))) {} : runner_(
Runner::Create(file_system, file_path, mode, std::move(callback))) {}
ScopedFileOpener::~ScopedFileOpener() { ScopedFileOpener::~ScopedFileOpener() {
runner_->AbortOrClose(); runner_->AbortOrClose();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment