Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: net/base/file_stream_context.cc

Issue 189393002: net: Update FileStream to use base::File instead of PlatformFile. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "net/base/file_stream_context.h" 5 #include "net/base/file_stream_context.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/message_loop/message_loop_proxy.h" 8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/task_runner_util.h" 9 #include "base/task_runner_util.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 23 matching lines...) Expand all
34 : result(result), 34 : result(result),
35 os_error(os_error) { 35 os_error(os_error) {
36 } 36 }
37 37
38 // static 38 // static
39 FileStream::Context::IOResult FileStream::Context::IOResult::FromOSError( 39 FileStream::Context::IOResult FileStream::Context::IOResult::FromOSError(
40 int64 os_error) { 40 int64 os_error) {
41 return IOResult(MapSystemError(os_error), os_error); 41 return IOResult(MapSystemError(os_error), os_error);
42 } 42 }
43 43
44 FileStream::Context::OpenResult::OpenResult() 44 // ---------------------------------------------------------------------
45 : file(base::kInvalidPlatformFileValue) { 45
46 FileStream::Context::OpenResult::OpenResult() {
46 } 47 }
47 48
48 FileStream::Context::OpenResult::OpenResult(base::PlatformFile file, 49 FileStream::Context::OpenResult::OpenResult(base::File file,
49 IOResult error_code) 50 IOResult error_code)
50 : file(file), 51 : file(file.Pass()),
51 error_code(error_code) { 52 error_code(error_code) {
52 } 53 }
53 54
55 FileStream::Context::OpenResult::OpenResult(RValue other)
56 : file(other.object->file.Pass()),
57 error_code(other.object->error_code) {
58 }
59
60 FileStream::Context::OpenResult& FileStream::Context::OpenResult::operator=(
61 RValue other) {
62 if (this != other.object) {
63 file = other.object->file.Pass();
64 error_code = other.object->error_code;
65 }
66 return *this;
67 }
68
69 // ---------------------------------------------------------------------
70
54 void FileStream::Context::Orphan() { 71 void FileStream::Context::Orphan() {
55 DCHECK(!orphaned_); 72 DCHECK(!orphaned_);
56 73
57 orphaned_ = true; 74 orphaned_ = true;
58 if (file_ != base::kInvalidPlatformFileValue) 75 if (file_.IsValid())
59 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_OPEN); 76 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_OPEN);
60 77
61 if (!async_in_progress_) { 78 if (!async_in_progress_) {
62 CloseAndDelete(); 79 CloseAndDelete();
63 } else if (file_ != base::kInvalidPlatformFileValue) { 80 } else if (file_.IsValid()) {
64 CancelIo(file_); 81 CancelIo(file_.GetPlatformFile());
65 } 82 }
66 } 83 }
67 84
68 void FileStream::Context::OpenAsync(const base::FilePath& path, 85 void FileStream::Context::OpenAsync(const base::FilePath& path,
69 int open_flags, 86 int open_flags,
70 const CompletionCallback& callback) { 87 const CompletionCallback& callback) {
71 DCHECK(!async_in_progress_); 88 DCHECK(!async_in_progress_);
72
73 BeginOpenEvent(path); 89 BeginOpenEvent(path);
74 90
75 const bool posted = base::PostTaskAndReplyWithResult( 91 bool posted = base::PostTaskAndReplyWithResult(
76 task_runner_.get(), 92 task_runner_.get(),
77 FROM_HERE, 93 FROM_HERE,
78 base::Bind( 94 base::Bind(
79 &Context::OpenFileImpl, base::Unretained(this), path, open_flags), 95 &Context::OpenFileImpl, base::Unretained(this), path, open_flags),
80 base::Bind(&Context::OnOpenCompleted, base::Unretained(this), callback)); 96 base::Bind(&Context::OnOpenCompleted, base::Unretained(this), callback));
81 DCHECK(posted); 97 DCHECK(posted);
82 98
83 async_in_progress_ = true; 99 async_in_progress_ = true;
100
101 // TODO(rvargas): Figure out what to do here. For POSIX, async IO is
102 // implemented by doing blocking IO on another thread, so file_ is not really
103 // async, but this code has sync and async paths so it has random checks to
104 // figure out what mode to use. We should probably make this class async only,
105 // and make consumers of sync IO use base::File.
106 async_ = true;
84 } 107 }
85 108
86 int FileStream::Context::OpenSync(const base::FilePath& path, int open_flags) { 109 int FileStream::Context::OpenSync(const base::FilePath& path, int open_flags) {
87 DCHECK(!async_in_progress_); 110 DCHECK(!async_in_progress_);
88 111
89 BeginOpenEvent(path); 112 BeginOpenEvent(path);
90 OpenResult result = OpenFileImpl(path, open_flags); 113 OpenResult result = OpenFileImpl(path, open_flags);
91 file_ = result.file; 114 if (result.file.IsValid()) {
92 if (file_ == base::kInvalidPlatformFileValue) { 115 file_ = result.file.Pass();
93 ProcessOpenError(result.error_code);
94 } else {
95 // TODO(satorux): Remove this once all async clients are migrated to use 116 // TODO(satorux): Remove this once all async clients are migrated to use
96 // Open(). crbug.com/114783 117 // Open(). crbug.com/114783
97 if (open_flags & base::PLATFORM_FILE_ASYNC) 118 if (open_flags & base::File::FLAG_ASYNC)
98 OnAsyncFileOpened(); 119 OnAsyncFileOpened();
120 } else {
121 ProcessOpenError(result.error_code);
99 } 122 }
100 return result.error_code.result; 123 return result.error_code.result;
101 } 124 }
102 125
103 void FileStream::Context::CloseSync() { 126 void FileStream::Context::CloseSync() {
104 DCHECK(!async_in_progress_); 127 DCHECK(!async_in_progress_);
105 if (file_ != base::kInvalidPlatformFileValue) { 128 if (file_.IsValid()) {
106 base::ClosePlatformFile(file_); 129 file_.Close();
107 file_ = base::kInvalidPlatformFileValue;
108 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_OPEN); 130 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_OPEN);
109 } 131 }
110 } 132 }
111 133
112 void FileStream::Context::CloseAsync(const CompletionCallback& callback) { 134 void FileStream::Context::CloseAsync(const CompletionCallback& callback) {
113 DCHECK(!async_in_progress_); 135 DCHECK(!async_in_progress_);
114 const bool posted = base::PostTaskAndReplyWithResult( 136 bool posted = base::PostTaskAndReplyWithResult(
115 task_runner_.get(), 137 task_runner_.get(),
116 FROM_HERE, 138 FROM_HERE,
117 base::Bind(&Context::CloseFileImpl, base::Unretained(this)), 139 base::Bind(&Context::CloseFileImpl, base::Unretained(this)),
118 base::Bind(&Context::ProcessAsyncResult, 140 base::Bind(&Context::ProcessAsyncResult,
119 base::Unretained(this), 141 base::Unretained(this),
120 IntToInt64(callback), 142 IntToInt64(callback),
121 FILE_ERROR_SOURCE_CLOSE)); 143 FILE_ERROR_SOURCE_CLOSE));
122 DCHECK(posted); 144 DCHECK(posted);
123 145
124 async_in_progress_ = true; 146 async_in_progress_ = true;
125 } 147 }
126 148
127 void FileStream::Context::SeekAsync(Whence whence, 149 void FileStream::Context::SeekAsync(Whence whence,
128 int64 offset, 150 int64 offset,
129 const Int64CompletionCallback& callback) { 151 const Int64CompletionCallback& callback) {
130 DCHECK(!async_in_progress_); 152 DCHECK(!async_in_progress_);
131 153
132 const bool posted = base::PostTaskAndReplyWithResult( 154 bool posted = base::PostTaskAndReplyWithResult(
133 task_runner_.get(), 155 task_runner_.get(),
134 FROM_HERE, 156 FROM_HERE,
135 base::Bind( 157 base::Bind(
136 &Context::SeekFileImpl, base::Unretained(this), whence, offset), 158 &Context::SeekFileImpl, base::Unretained(this), whence, offset),
137 base::Bind(&Context::ProcessAsyncResult, 159 base::Bind(&Context::ProcessAsyncResult,
138 base::Unretained(this), 160 base::Unretained(this),
139 callback, 161 callback,
140 FILE_ERROR_SOURCE_SEEK)); 162 FILE_ERROR_SOURCE_SEEK));
141 DCHECK(posted); 163 DCHECK(posted);
142 164
143 async_in_progress_ = true; 165 async_in_progress_ = true;
144 } 166 }
145 167
146 int64 FileStream::Context::SeekSync(Whence whence, int64 offset) { 168 int64 FileStream::Context::SeekSync(Whence whence, int64 offset) {
147 IOResult result = SeekFileImpl(whence, offset); 169 IOResult result = SeekFileImpl(whence, offset);
148 RecordError(result, FILE_ERROR_SOURCE_SEEK); 170 RecordError(result, FILE_ERROR_SOURCE_SEEK);
149 return result.result; 171 return result.result;
150 } 172 }
151 173
152 void FileStream::Context::FlushAsync(const CompletionCallback& callback) { 174 void FileStream::Context::FlushAsync(const CompletionCallback& callback) {
153 DCHECK(!async_in_progress_); 175 DCHECK(!async_in_progress_);
154 176
155 const bool posted = base::PostTaskAndReplyWithResult( 177 bool posted = base::PostTaskAndReplyWithResult(
156 task_runner_.get(), 178 task_runner_.get(),
157 FROM_HERE, 179 FROM_HERE,
158 base::Bind(&Context::FlushFileImpl, base::Unretained(this)), 180 base::Bind(&Context::FlushFileImpl, base::Unretained(this)),
159 base::Bind(&Context::ProcessAsyncResult, 181 base::Bind(&Context::ProcessAsyncResult,
160 base::Unretained(this), 182 base::Unretained(this),
161 IntToInt64(callback), 183 IntToInt64(callback),
162 FILE_ERROR_SOURCE_FLUSH)); 184 FILE_ERROR_SOURCE_FLUSH));
163 DCHECK(posted); 185 DCHECK(posted);
164 186
165 async_in_progress_ = true; 187 async_in_progress_ = true;
(...skipping 24 matching lines...) Expand all
190 } 212 }
191 213
192 void FileStream::Context::BeginOpenEvent(const base::FilePath& path) { 214 void FileStream::Context::BeginOpenEvent(const base::FilePath& path) {
193 std::string file_name = path.AsUTF8Unsafe(); 215 std::string file_name = path.AsUTF8Unsafe();
194 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_OPEN, 216 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_OPEN,
195 NetLog::StringCallback("file_name", &file_name)); 217 NetLog::StringCallback("file_name", &file_name));
196 } 218 }
197 219
198 FileStream::Context::OpenResult FileStream::Context::OpenFileImpl( 220 FileStream::Context::OpenResult FileStream::Context::OpenFileImpl(
199 const base::FilePath& path, int open_flags) { 221 const base::FilePath& path, int open_flags) {
200 base::PlatformFile file; 222 #if defined(OS_POSIX)
223 // Always use blocking IO.
224 open_flags &= ~base::File::FLAG_ASYNC;
225 #endif
226 base::File file;
201 #if defined(OS_ANDROID) 227 #if defined(OS_ANDROID)
202 if (path.IsContentUri()) { 228 if (path.IsContentUri()) {
203 // Check that only Read flags are set. 229 // Check that only Read flags are set.
204 DCHECK_EQ(open_flags & ~base::PLATFORM_FILE_ASYNC, 230 DCHECK_EQ(open_flags & ~base::File::FLAG_ASYNC,
205 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); 231 base::File::FLAG_OPEN | base::File::FLAG_READ);
206 file = base::OpenContentUriForRead(path); 232 file = base::OpenContentUriForRead(path);
207 } else { 233 } else {
208 #endif // defined(OS_ANDROID) 234 #endif // defined(OS_ANDROID)
209 // FileStream::Context actually closes the file asynchronously, 235 // FileStream::Context actually closes the file asynchronously,
210 // independently from FileStream's destructor. It can cause problems for 236 // independently from FileStream's destructor. It can cause problems for
211 // users wanting to delete the file right after FileStream deletion. Thus 237 // users wanting to delete the file right after FileStream deletion. Thus
212 // we are always adding SHARE_DELETE flag to accommodate such use case. 238 // we are always adding SHARE_DELETE flag to accommodate such use case.
213 open_flags |= base::PLATFORM_FILE_SHARE_DELETE; 239 // TODO(rvargas): This sounds like a bug, as deleting the file would
214 file = base::CreatePlatformFile(path, open_flags, NULL, NULL); 240 // presumably happen on the wrong thread. There should be an async delete.
241 open_flags |= base::File::FLAG_SHARE_DELETE;
242 file.Initialize(path, open_flags);
215 #if defined(OS_ANDROID) 243 #if defined(OS_ANDROID)
216 } 244 }
217 #endif // defined(OS_ANDROID) 245 #endif // defined(OS_ANDROID)
218 if (file == base::kInvalidPlatformFileValue) 246 if (!file.IsValid())
219 return OpenResult(file, IOResult::FromOSError(GetLastErrno())); 247 return OpenResult(base::File(), IOResult::FromOSError(GetLastErrno()));
220 248
221 return OpenResult(file, IOResult(OK, 0)); 249 return OpenResult(file.Pass(), IOResult(OK, 0));
250 }
251
252 FileStream::Context::IOResult FileStream::Context::CloseFileImpl() {
253 file_.Close();
254 return IOResult(OK, 0);
222 } 255 }
223 256
224 void FileStream::Context::ProcessOpenError(const IOResult& error_code) { 257 void FileStream::Context::ProcessOpenError(const IOResult& error_code) {
225 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_OPEN); 258 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_OPEN);
226 RecordError(error_code, FILE_ERROR_SOURCE_OPEN); 259 RecordError(error_code, FILE_ERROR_SOURCE_OPEN);
227 } 260 }
228 261
229 void FileStream::Context::OnOpenCompleted(const CompletionCallback& callback, 262 void FileStream::Context::OnOpenCompleted(const CompletionCallback& callback,
230 OpenResult open_result) { 263 OpenResult open_result) {
231 file_ = open_result.file; 264 if (!open_result.file.IsValid()) {
232 if (file_ == base::kInvalidPlatformFileValue)
233 ProcessOpenError(open_result.error_code); 265 ProcessOpenError(open_result.error_code);
234 else if (!orphaned_) 266 } else if (!orphaned_) {
267 file_ = open_result.file.Pass();
235 OnAsyncFileOpened(); 268 OnAsyncFileOpened();
269 }
236 OnAsyncCompleted(IntToInt64(callback), open_result.error_code.result); 270 OnAsyncCompleted(IntToInt64(callback), open_result.error_code.result);
237 } 271 }
238 272
239 void FileStream::Context::CloseAndDelete() { 273 void FileStream::Context::CloseAndDelete() {
240 DCHECK(!async_in_progress_); 274 DCHECK(!async_in_progress_);
241 275
242 if (file_ == base::kInvalidPlatformFileValue) { 276 if (file_.IsValid()) {
243 delete this; 277 bool posted = task_runner_.get()->PostTaskAndReply(
244 } else {
245 const bool posted = task_runner_->PostTaskAndReply(
246 FROM_HERE, 278 FROM_HERE,
247 base::Bind(base::IgnoreResult(&base::ClosePlatformFile), file_), 279 base::Bind(base::IgnoreResult(&Context::CloseFileImpl),
280 base::Unretained(this)),
248 base::Bind(&Context::OnCloseCompleted, base::Unretained(this))); 281 base::Bind(&Context::OnCloseCompleted, base::Unretained(this)));
249 DCHECK(posted); 282 DCHECK(posted);
250 file_ = base::kInvalidPlatformFileValue; 283 } else {
284 delete this;
251 } 285 }
252 } 286 }
253 287
254 void FileStream::Context::OnCloseCompleted() { 288 void FileStream::Context::OnCloseCompleted() {
255 delete this; 289 delete this;
256 } 290 }
257 291
258 Int64CompletionCallback FileStream::Context::IntToInt64( 292 Int64CompletionCallback FileStream::Context::IntToInt64(
259 const CompletionCallback& callback) { 293 const CompletionCallback& callback) {
260 return base::Bind(&CallInt64ToInt, callback); 294 return base::Bind(&CallInt64ToInt, callback);
(...skipping 15 matching lines...) Expand all
276 // operation is in progress. 310 // operation is in progress.
277 async_in_progress_ = false; 311 async_in_progress_ = false;
278 if (orphaned_) 312 if (orphaned_)
279 CloseAndDelete(); 313 CloseAndDelete();
280 else 314 else
281 callback.Run(result); 315 callback.Run(result);
282 } 316 }
283 317
284 } // namespace net 318 } // namespace net
285 319
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698