Skip to content

Commit 2b609d7

Browse files
author
rvargas@chromium.org
committed
Base: Make FileProxy automaticaly close the file on a worker thread.
This CL removes the restriction that callers should call Close before deleting the object if they want to make sure the file is not closed on the current thread. BUG=322664 TEST=base_unittests Review URL: https://codereview.chromium.org/231703002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263675 0039d316-1c4b-4281-b951-d872f2087c98
1 parent 0d66b19 commit 2b609d7

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

base/files/file.cc

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ File::File(RValue other)
6060
}
6161

6262
File::~File() {
63+
// Go through the AssertIOAllowed logic.
64+
Close();
6365
}
6466

6567
File& File::operator=(RValue other) {

base/files/file_proxy.cc

+16-6
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,38 @@
1313
#include "base/task_runner.h"
1414
#include "base/task_runner_util.h"
1515

16+
namespace {
17+
18+
void FileDeleter(base::File file) {
19+
}
20+
21+
} // namespace
22+
1623
namespace base {
1724

1825
class FileHelper {
1926
public:
2027
FileHelper(FileProxy* proxy, File file)
2128
: file_(file.Pass()),
22-
proxy_(AsWeakPtr(proxy)),
23-
error_(File::FILE_ERROR_FAILED) {
29+
error_(File::FILE_ERROR_FAILED),
30+
task_runner_(proxy->task_runner()),
31+
proxy_(AsWeakPtr(proxy)) {
2432
}
2533

2634
void PassFile() {
2735
if (proxy_)
2836
proxy_->SetFile(file_.Pass());
37+
else if (file_.IsValid())
38+
task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
2939
}
3040

3141
protected:
3242
File file_;
33-
WeakPtr<FileProxy> proxy_;
3443
File::Error error_;
3544

3645
private:
46+
scoped_refptr<TaskRunner> task_runner_;
47+
WeakPtr<FileProxy> proxy_;
3748
DISALLOW_COPY_AND_ASSIGN(FileHelper);
3849
};
3950

@@ -219,13 +230,12 @@ class WriteHelper : public FileHelper {
219230

220231
} // namespace
221232

222-
FileProxy::FileProxy() : task_runner_(NULL) {
223-
}
224-
225233
FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) {
226234
}
227235

228236
FileProxy::~FileProxy() {
237+
if (file_.IsValid())
238+
task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
229239
}
230240

231241
bool FileProxy::CreateOrOpen(const FilePath& file_path,

base/files/file_proxy.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,8 @@ class Time;
2525
// same rules of the equivalent File method, as they are implemented by bouncing
2626
// the operation to File using a TaskRunner.
2727
//
28-
// This class does NOT perform automatic proxying to close the underlying file
29-
// at destruction, which means that it may potentially close the file in the
30-
// wrong thread (the current thread). If that is not appropriate, the caller
31-
// must ensure that Close() is called, so that the operation happens on the
32-
// desired thread.
28+
// This class performs automatic proxying to close the underlying file at
29+
// destruction.
3330
//
3431
// The TaskRunner is in charge of any sequencing of the operations, but a single
3532
// operation can be proxied at a time, regardless of the use of a callback.
@@ -131,6 +128,7 @@ class BASE_EXPORT FileProxy : public SupportsWeakPtr<FileProxy> {
131128
private:
132129
friend class FileHelper;
133130
void SetFile(File file);
131+
TaskRunner* task_runner() { return task_runner_.get(); }
134132

135133
scoped_refptr<TaskRunner> task_runner_;
136134
File file_;

base/files/file_proxy_unittest.cc

+16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "base/memory/weak_ptr.h"
1515
#include "base/message_loop/message_loop.h"
1616
#include "base/threading/thread.h"
17+
#include "base/threading/thread_restrictions.h"
1718
#include "testing/gtest/include/gtest/gtest.h"
1819

1920
namespace base {
@@ -143,6 +144,21 @@ TEST_F(FileProxyTest, CreateOrOpen_OpenNonExistent) {
143144
EXPECT_FALSE(PathExists(test_path()));
144145
}
145146

147+
TEST_F(FileProxyTest, CreateOrOpen_AbandonedCreate) {
148+
bool prev = ThreadRestrictions::SetIOAllowed(false);
149+
{
150+
FileProxy proxy(file_task_runner());
151+
proxy.CreateOrOpen(
152+
test_path(),
153+
File::FLAG_CREATE | File::FLAG_READ,
154+
Bind(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
155+
}
156+
MessageLoop::current()->Run();
157+
ThreadRestrictions::SetIOAllowed(prev);
158+
159+
EXPECT_TRUE(PathExists(test_path()));
160+
}
161+
146162
TEST_F(FileProxyTest, Close) {
147163
// Creates a file.
148164
FileProxy proxy(file_task_runner());

0 commit comments

Comments
 (0)