From 663589d1aaea88b2ccb0c3b91040e30ab79f0d35 Mon Sep 17 00:00:00 2001 From: "rvargas@google.com" Date: Wed, 21 Oct 2009 22:24:44 +0000 Subject: Disk cache: Fix a race accessing a file's reference counter from a worker thread. BUG=24307 TEST=current unit tests / valgrind Review URL: http://codereview.chromium.org/309001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29720 0039d316-1c4b-4281-b951-d872f2087c98 --- net/disk_cache/file_posix.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/disk_cache/file_posix.cc b/net/disk_cache/file_posix.cc index d3e903b..3ffdb45 100644 --- a/net/disk_cache/file_posix.cc +++ b/net/disk_cache/file_posix.cc @@ -70,13 +70,17 @@ class BackgroundIO : public base::RefCountedThreadSafe { return callback_; } + disk_cache::File* file() { + return file_; + } + private: - // An event to signal when the operation completes, and the user callback tha + // An event to signal when the operation completes, and the user callback that // has to be invoked. These members are accessed directly by the controller. base::WaitableEvent io_completed_; disk_cache::FileIOCallback* callback_; - scoped_refptr file_; + disk_cache::File* file_; const void* buf_; size_t buf_len_; size_t offset_; @@ -186,6 +190,7 @@ void InFlightIO::PostRead(disk_cache::File *file, void* buf, size_t buf_len, scoped_refptr operation = new BackgroundIO(file, buf, buf_len, offset, callback, this); io_list_.insert(operation.get()); + file->AddRef(); // Balanced on InvokeCallback() WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(operation.get(), &BackgroundIO::Read), @@ -199,6 +204,7 @@ void InFlightIO::PostWrite(disk_cache::File* file, const void* buf, scoped_refptr operation = new BackgroundIO(file, buf, buf_len, offset, callback, this); io_list_.insert(operation.get()); + file->AddRef(); // Balanced on InvokeCallback() WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(operation.get(), &BackgroundIO::Write, @@ -232,7 +238,8 @@ void InFlightIO::InvokeCallback(BackgroundIO* operation, bool cancel_task) { disk_cache::FileIOCallback* callback = operation->callback(); int bytes = operation->Result(); - // Release the reference acquired in PostRead / PostWrite. + // Release the references acquired in PostRead / PostWrite. + operation->file()->Release(); io_list_.erase(operation); callback->OnFileIOComplete(bytes); } -- cgit v1.1