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

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

Issue 9949011: Make FileStream::Seek async and add FileStream::SeekSync for sync operation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 8 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
« no previous file with comments | « net/base/file_stream_posix.h ('k') | net/base/file_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // For 64-bit file access (off_t = off64_t, lseek64, etc). 5 // For 64-bit file access (off_t = off64_t, lseek64, etc).
6 #define _FILE_OFFSET_BITS 64 6 #define _FILE_OFFSET_BITS 64
7 7
8 #include "net/base/file_stream.h" 8 #include "net/base/file_stream.h"
9 9
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 118
119 // Closes a file with CloseFile() and signals the completion. 119 // Closes a file with CloseFile() and signals the completion.
120 void CloseFileAndSignal(base::PlatformFile* file, 120 void CloseFileAndSignal(base::PlatformFile* file,
121 base::WaitableEvent* on_io_complete, 121 base::WaitableEvent* on_io_complete,
122 const net::BoundNetLog& bound_net_log) { 122 const net::BoundNetLog& bound_net_log) {
123 CloseFile(*file, bound_net_log); 123 CloseFile(*file, bound_net_log);
124 *file = base::kInvalidPlatformFileValue; 124 *file = base::kInvalidPlatformFileValue;
125 on_io_complete->Signal(); 125 on_io_complete->Signal();
126 } 126 }
127 127
128 // Adjusts the position from where the data is read.
129 void SeekFile(base::PlatformFile file,
130 Whence whence,
131 int64 offset,
132 int64* result,
133 bool record_uma,
134 const net::BoundNetLog& bound_net_log) {
135 off_t res = lseek(file, static_cast<off_t>(offset),
136 static_cast<int>(whence));
137 if (res == static_cast<off_t>(-1)) {
138 *result = RecordAndMapError(errno,
139 FILE_ERROR_SOURCE_SEEK,
140 record_uma,
141 bound_net_log);
142 return;
143 }
144 *result = res;
145 }
146
147 // Seeks a file by calling SeekSync() and signals the completion.
148 void SeekFileAndSignal(base::PlatformFile file,
149 Whence whence,
150 int64 offset,
151 int64* result,
152 bool record_uma,
153 base::WaitableEvent* on_io_complete,
154 const net::BoundNetLog& bound_net_log) {
155 SeekFile(file, whence, offset, result, record_uma, bound_net_log);
156 on_io_complete->Signal();
157 }
158
128 // ReadFile() is a simple wrapper around read() that handles EINTR signals and 159 // ReadFile() is a simple wrapper around read() that handles EINTR signals and
129 // calls MapSystemError() to map errno to net error codes. 160 // calls MapSystemError() to map errno to net error codes.
130 void ReadFile(base::PlatformFile file, 161 void ReadFile(base::PlatformFile file,
131 char* buf, 162 char* buf,
132 int buf_len, 163 int buf_len,
133 bool record_uma, 164 bool record_uma,
134 int* result, 165 int* result,
135 const net::BoundNetLog& bound_net_log) { 166 const net::BoundNetLog& bound_net_log) {
136 base::ThreadRestrictions::AssertIOAllowed(); 167 base::ThreadRestrictions::AssertIOAllowed();
137 // read(..., 0) returns 0 to indicate end-of-file. 168 // read(..., 0) returns 0 to indicate end-of-file.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 const net::BoundNetLog& bound_net_log) { 227 const net::BoundNetLog& bound_net_log) {
197 base::ThreadRestrictions::AssertIOAllowed(); 228 base::ThreadRestrictions::AssertIOAllowed();
198 ssize_t res = HANDLE_EINTR(fsync(file)); 229 ssize_t res = HANDLE_EINTR(fsync(file));
199 if (res == -1) { 230 if (res == -1) {
200 res = RecordAndMapError(errno, FILE_ERROR_SOURCE_FLUSH, record_uma, 231 res = RecordAndMapError(errno, FILE_ERROR_SOURCE_FLUSH, record_uma,
201 bound_net_log); 232 bound_net_log);
202 } 233 }
203 return res; 234 return res;
204 } 235 }
205 236
237 // Called when Read(), Write() or Seek() is completed.
238 // |result| contains the result or a network error code.
239 template <typename R>
240 void OnIOComplete(const base::WeakPtr<FileStreamPosix>& stream,
241 const base::Callback<void(R)>& callback,
242 R* result) {
243 if (!stream.get())
244 return;
245
246 // Reset this before Run() as Run() may issue a new async operation.
247 stream->ResetOnIOComplete();
248 callback.Run(*result);
249 }
250
206 } // namespace 251 } // namespace
207 252
208 // FileStreamPosix ------------------------------------------------------------ 253 // FileStreamPosix ------------------------------------------------------------
209 254
210 FileStreamPosix::FileStreamPosix(net::NetLog* net_log) 255 FileStreamPosix::FileStreamPosix(net::NetLog* net_log)
211 : file_(base::kInvalidPlatformFileValue), 256 : file_(base::kInvalidPlatformFileValue),
212 open_flags_(0), 257 open_flags_(0),
213 auto_closed_(true), 258 auto_closed_(true),
214 record_uma_(false), 259 record_uma_(false),
215 bound_net_log_(net::BoundNetLog::Make(net_log, 260 bound_net_log_(net::BoundNetLog::Make(net_log,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } else { 295 } else {
251 CloseSync(); 296 CloseSync();
252 } 297 }
253 } 298 }
254 299
255 bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL); 300 bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL);
256 } 301 }
257 302
258 void FileStreamPosix::Close(const CompletionCallback& callback) { 303 void FileStreamPosix::Close(const CompletionCallback& callback) {
259 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 304 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
260 DCHECK(callback_.is_null());
261 305
262 callback_ = callback; 306 DCHECK(!weak_ptr_factory_.HasWeakPtrs());
263
264 DCHECK(!on_io_complete_.get()); 307 DCHECK(!on_io_complete_.get());
265 on_io_complete_.reset(new base::WaitableEvent( 308 on_io_complete_.reset(new base::WaitableEvent(
266 false /* manual_reset */, false /* initially_signaled */)); 309 false /* manual_reset */, false /* initially_signaled */));
267 310
268 // Passing &file_ to a thread pool looks unsafe but it's safe here as the 311 // Passing &file_ to a thread pool looks unsafe but it's safe here as the
269 // destructor ensures that the close operation is complete with 312 // destructor ensures that the close operation is complete with
270 // WaitForIOCompletion(). See also the destructor. 313 // WaitForIOCompletion(). See also the destructor.
271 const bool posted = base::WorkerPool::PostTaskAndReply( 314 const bool posted = base::WorkerPool::PostTaskAndReply(
272 FROM_HERE, 315 FROM_HERE,
273 base::Bind(&CloseFileAndSignal, &file_, on_io_complete_.get(), 316 base::Bind(&CloseFileAndSignal, &file_, on_io_complete_.get(),
274 bound_net_log_), 317 bound_net_log_),
275 base::Bind(&FileStreamPosix::OnClosed, 318 base::Bind(&FileStreamPosix::OnClosed,
276 weak_ptr_factory_.GetWeakPtr()), 319 weak_ptr_factory_.GetWeakPtr(),
320 callback),
277 true /* task_is_slow */); 321 true /* task_is_slow */);
278 322
279 DCHECK(posted); 323 DCHECK(posted);
280 } 324 }
281 325
282 void FileStreamPosix::CloseSync() { 326 void FileStreamPosix::CloseSync() {
283 // TODO(satorux): Replace the following async stuff with a 327 // TODO(satorux): Replace the following async stuff with a
284 // DCHECK(open_flags & ASYNC) once once all async clients are migrated to 328 // DCHECK(open_flags & ASYNC) once once all async clients are migrated to
285 // use Close(). crbug.com/114783 329 // use Close(). crbug.com/114783
286 330
287 // Abort any existing asynchronous operations. 331 // Abort any existing asynchronous operations.
288 weak_ptr_factory_.InvalidateWeakPtrs(); 332 weak_ptr_factory_.InvalidateWeakPtrs();
289 // Block until the last open/read/write operation is complete. 333 // Block until the last open/read/write operation is complete.
290 // TODO(satorux): Ideally we should not block. crbug.com/115067 334 // TODO(satorux): Ideally we should not block. crbug.com/115067
291 WaitForIOCompletion(); 335 WaitForIOCompletion();
292 336
293 CloseFile(file_, bound_net_log_); 337 CloseFile(file_, bound_net_log_);
294 file_ = base::kInvalidPlatformFileValue; 338 file_ = base::kInvalidPlatformFileValue;
295 } 339 }
296 340
297 int FileStreamPosix::Open(const FilePath& path, int open_flags, 341 int FileStreamPosix::Open(const FilePath& path, int open_flags,
298 const CompletionCallback& callback) { 342 const CompletionCallback& callback) {
299 if (IsOpen()) { 343 if (IsOpen()) {
300 DLOG(FATAL) << "File is already open!"; 344 DLOG(FATAL) << "File is already open!";
301 return ERR_UNEXPECTED; 345 return ERR_UNEXPECTED;
302 } 346 }
303 347
304 DCHECK(callback_.is_null());
305 callback_ = callback;
306
307 open_flags_ = open_flags; 348 open_flags_ = open_flags;
308 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 349 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
309 350
351 DCHECK(!weak_ptr_factory_.HasWeakPtrs());
310 DCHECK(!on_io_complete_.get()); 352 DCHECK(!on_io_complete_.get());
311 on_io_complete_.reset(new base::WaitableEvent( 353 on_io_complete_.reset(new base::WaitableEvent(
312 false /* manual_reset */, false /* initially_signaled */)); 354 false /* manual_reset */, false /* initially_signaled */));
313 355
314 // Passing &file_ to a thread pool looks unsafe but it's safe here as the 356 // Passing &file_ to a thread pool looks unsafe but it's safe here as the
315 // destructor ensures that the open operation is complete with 357 // destructor ensures that the open operation is complete with
316 // WaitForIOCompletion(). See also the destructor. 358 // WaitForIOCompletion(). See also the destructor.
317 int* result = new int(OK); 359 int* result = new int(OK);
318 const bool posted = base::WorkerPool::PostTaskAndReply( 360 const bool posted = base::WorkerPool::PostTaskAndReply(
319 FROM_HERE, 361 FROM_HERE,
320 base::Bind(&OpenFileAndSignal, 362 base::Bind(&OpenFileAndSignal,
321 path, open_flags, record_uma_, &file_, result, 363 path, open_flags, record_uma_, &file_, result,
322 on_io_complete_.get(), bound_net_log_), 364 on_io_complete_.get(), bound_net_log_),
323 base::Bind(&FileStreamPosix::OnIOComplete, 365 base::Bind(&OnIOComplete<int>, weak_ptr_factory_.GetWeakPtr(),
324 weak_ptr_factory_.GetWeakPtr(), 366 callback, base::Owned(result)),
325 base::Owned(result)),
326 true /* task_is_slow */); 367 true /* task_is_slow */);
327 DCHECK(posted); 368 DCHECK(posted);
328 return ERR_IO_PENDING; 369 return ERR_IO_PENDING;
329 } 370 }
330 371
331 int FileStreamPosix::OpenSync(const FilePath& path, int open_flags) { 372 int FileStreamPosix::OpenSync(const FilePath& path, int open_flags) {
332 if (IsOpen()) { 373 if (IsOpen()) {
333 DLOG(FATAL) << "File is already open!"; 374 DLOG(FATAL) << "File is already open!";
334 return ERR_UNEXPECTED; 375 return ERR_UNEXPECTED;
335 } 376 }
336 377
337 open_flags_ = open_flags; 378 open_flags_ = open_flags;
338 // TODO(satorux): Put a DCHECK once once all async clients are migrated 379 // TODO(satorux): Put a DCHECK once once all async clients are migrated
339 // to use Open(). crbug.com/114783 380 // to use Open(). crbug.com/114783
340 // 381 //
341 // DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC)); 382 // DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC));
342 383
343 int result = OK; 384 int result = OK;
344 OpenFile(path, open_flags_, record_uma_, &file_, &result, bound_net_log_); 385 OpenFile(path, open_flags_, record_uma_, &file_, &result, bound_net_log_);
345 return result; 386 return result;
346 } 387 }
347 388
348 bool FileStreamPosix::IsOpen() const { 389 bool FileStreamPosix::IsOpen() const {
349 return file_ != base::kInvalidPlatformFileValue; 390 return file_ != base::kInvalidPlatformFileValue;
350 } 391 }
351 392
352 int64 FileStreamPosix::Seek(Whence whence, int64 offset) { 393 int FileStreamPosix::Seek(Whence whence, int64 offset,
394 const Int64CompletionCallback& callback) {
395 if (!IsOpen())
396 return ERR_UNEXPECTED;
397
398 // Make sure we're async and we have no other in-flight async operations.
399 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
400 DCHECK(!weak_ptr_factory_.HasWeakPtrs());
401 DCHECK(!on_io_complete_.get());
402
403 on_io_complete_.reset(new base::WaitableEvent(
404 false /* manual_reset */, false /* initially_signaled */));
405
406 int64* result = new int64(-1);
407 const bool posted = base::WorkerPool::PostTaskAndReply(
408 FROM_HERE,
409 base::Bind(&SeekFileAndSignal, file_, whence, offset, result,
410 record_uma_, on_io_complete_.get(), bound_net_log_),
411 base::Bind(&OnIOComplete<int64>,
412 weak_ptr_factory_.GetWeakPtr(),
413 callback, base::Owned(result)),
414 true /* task is slow */);
415 DCHECK(posted);
416 return ERR_IO_PENDING;
417 }
418
419 int64 FileStreamPosix::SeekSync(Whence whence, int64 offset) {
353 base::ThreadRestrictions::AssertIOAllowed(); 420 base::ThreadRestrictions::AssertIOAllowed();
354 421
355 if (!IsOpen()) 422 if (!IsOpen())
356 return ERR_UNEXPECTED; 423 return ERR_UNEXPECTED;
357 424
358 // If we're in async, make sure we don't have a request in flight. 425 // If we're in async, make sure we don't have a request in flight.
359 DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC) || 426 DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC) ||
360 callback_.is_null()); 427 !on_io_complete_.get());
361 428
362 off_t res = lseek(file_, static_cast<off_t>(offset), 429 off_t result = -1;
363 static_cast<int>(whence)); 430 SeekFile(file_, whence, offset, &result, record_uma_, bound_net_log_);
364 if (res == static_cast<off_t>(-1)) { 431 return result;
365 return RecordAndMapError(errno,
366 FILE_ERROR_SOURCE_SEEK,
367 record_uma_,
368 bound_net_log_);
369 }
370
371 return res;
372 } 432 }
373 433
374 int64 FileStreamPosix::Available() { 434 int64 FileStreamPosix::Available() {
375 base::ThreadRestrictions::AssertIOAllowed(); 435 base::ThreadRestrictions::AssertIOAllowed();
376 436
377 if (!IsOpen()) 437 if (!IsOpen())
378 return ERR_UNEXPECTED; 438 return ERR_UNEXPECTED;
379 439
380 int64 cur_pos = Seek(FROM_CURRENT, 0); 440 int64 cur_pos = SeekSync(FROM_CURRENT, 0);
381 if (cur_pos < 0) 441 if (cur_pos < 0)
382 return cur_pos; 442 return cur_pos;
383 443
384 struct stat info; 444 struct stat info;
385 if (fstat(file_, &info) != 0) { 445 if (fstat(file_, &info) != 0) {
386 return RecordAndMapError(errno, 446 return RecordAndMapError(errno,
387 FILE_ERROR_SOURCE_GET_SIZE, 447 FILE_ERROR_SOURCE_GET_SIZE,
388 record_uma_, 448 record_uma_,
389 bound_net_log_); 449 bound_net_log_);
390 } 450 }
391 451
392 int64 size = static_cast<int64>(info.st_size); 452 int64 size = static_cast<int64>(info.st_size);
393 DCHECK_GT(size, cur_pos); 453 DCHECK_GT(size, cur_pos);
394 454
395 return size - cur_pos; 455 return size - cur_pos;
396 } 456 }
397 457
398 int FileStreamPosix::Read( 458 int FileStreamPosix::Read(
399 IOBuffer* in_buf, int buf_len, const CompletionCallback& callback) { 459 IOBuffer* in_buf, int buf_len, const CompletionCallback& callback) {
400 if (!IsOpen()) 460 if (!IsOpen())
401 return ERR_UNEXPECTED; 461 return ERR_UNEXPECTED;
402 462
403 // read(..., 0) will return 0, which indicates end-of-file. 463 // read(..., 0) will return 0, which indicates end-of-file.
404 DCHECK_GT(buf_len, 0); 464 DCHECK_GT(buf_len, 0);
405 DCHECK(open_flags_ & base::PLATFORM_FILE_READ); 465 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
406 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 466 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
467
407 // Make sure we don't have a request in flight. 468 // Make sure we don't have a request in flight.
408 DCHECK(callback_.is_null()); 469 DCHECK(!weak_ptr_factory_.HasWeakPtrs());
470 DCHECK(!on_io_complete_.get());
409 471
410 callback_ = callback; 472 on_io_complete_.reset(new base::WaitableEvent(
473 false /* manual_reset */, false /* initially_signaled */));
474
411 int* result = new int(OK); 475 int* result = new int(OK);
412 scoped_refptr<IOBuffer> buf = in_buf; 476 scoped_refptr<IOBuffer> buf = in_buf;
413 DCHECK(!on_io_complete_.get());
414 on_io_complete_.reset(new base::WaitableEvent(
415 false /* manual_reset */, false /* initially_signaled */));
416 const bool posted = base::WorkerPool::PostTaskAndReply( 477 const bool posted = base::WorkerPool::PostTaskAndReply(
417 FROM_HERE, 478 FROM_HERE,
418 base::Bind(&ReadFileAndSignal, file_, buf, buf_len, 479 base::Bind(&ReadFileAndSignal, file_, buf, buf_len,
419 record_uma_, result, on_io_complete_.get(), bound_net_log_), 480 record_uma_, result, on_io_complete_.get(), bound_net_log_),
420 base::Bind(&FileStreamPosix::OnIOComplete, 481 base::Bind(&OnIOComplete<int>,
421 weak_ptr_factory_.GetWeakPtr(), 482 weak_ptr_factory_.GetWeakPtr(),
422 base::Owned(result)), 483 callback, base::Owned(result)),
423 true /* task is slow */); 484 true /* task is slow */);
424 DCHECK(posted); 485 DCHECK(posted);
425 return ERR_IO_PENDING; 486 return ERR_IO_PENDING;
426 } 487 }
427 488
428 int FileStreamPosix::ReadSync(char* buf, int buf_len) { 489 int FileStreamPosix::ReadSync(char* buf, int buf_len) {
429 if (!IsOpen()) 490 if (!IsOpen())
430 return ERR_UNEXPECTED; 491 return ERR_UNEXPECTED;
431 492
432 DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC)); 493 DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC));
(...skipping 29 matching lines...) Expand all
462 523
463 int FileStreamPosix::Write( 524 int FileStreamPosix::Write(
464 IOBuffer* in_buf, int buf_len, const CompletionCallback& callback) { 525 IOBuffer* in_buf, int buf_len, const CompletionCallback& callback) {
465 if (!IsOpen()) 526 if (!IsOpen())
466 return ERR_UNEXPECTED; 527 return ERR_UNEXPECTED;
467 528
468 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 529 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
469 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 530 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
470 // write(..., 0) will return 0, which indicates end-of-file. 531 // write(..., 0) will return 0, which indicates end-of-file.
471 DCHECK_GT(buf_len, 0); 532 DCHECK_GT(buf_len, 0);
533
472 // Make sure we don't have a request in flight. 534 // Make sure we don't have a request in flight.
473 DCHECK(callback_.is_null()); 535 DCHECK(!weak_ptr_factory_.HasWeakPtrs());
474
475 callback_ = callback;
476 int* result = new int(OK);
477 scoped_refptr<IOBuffer> buf = in_buf;
478 DCHECK(!on_io_complete_.get()); 536 DCHECK(!on_io_complete_.get());
479 on_io_complete_.reset(new base::WaitableEvent( 537 on_io_complete_.reset(new base::WaitableEvent(
480 false /* manual_reset */, false /* initially_signaled */)); 538 false /* manual_reset */, false /* initially_signaled */));
539
540 int* result = new int(OK);
541 scoped_refptr<IOBuffer> buf = in_buf;
481 const bool posted = base::WorkerPool::PostTaskAndReply( 542 const bool posted = base::WorkerPool::PostTaskAndReply(
482 FROM_HERE, 543 FROM_HERE,
483 base::Bind(&WriteFileAndSignal, file_, buf, buf_len, 544 base::Bind(&WriteFileAndSignal, file_, buf, buf_len,
484 record_uma_, result, on_io_complete_.get(), bound_net_log_), 545 record_uma_, result, on_io_complete_.get(), bound_net_log_),
485 base::Bind(&FileStreamPosix::OnIOComplete, 546 base::Bind(&OnIOComplete<int>,
486 weak_ptr_factory_.GetWeakPtr(), 547 weak_ptr_factory_.GetWeakPtr(),
487 base::Owned(result)), 548 callback, base::Owned(result)),
488 true /* task is slow */); 549 true /* task is slow */);
489 DCHECK(posted); 550 DCHECK(posted);
490 return ERR_IO_PENDING; 551 return ERR_IO_PENDING;
491 } 552 }
492 553
493 int FileStreamPosix::WriteSync( 554 int FileStreamPosix::WriteSync(
494 const char* buf, int buf_len) { 555 const char* buf, int buf_len) {
495 if (!IsOpen()) 556 if (!IsOpen())
496 return ERR_UNEXPECTED; 557 return ERR_UNEXPECTED;
497 558
(...skipping 10 matching lines...) Expand all
508 int64 FileStreamPosix::Truncate(int64 bytes) { 569 int64 FileStreamPosix::Truncate(int64 bytes) {
509 base::ThreadRestrictions::AssertIOAllowed(); 570 base::ThreadRestrictions::AssertIOAllowed();
510 571
511 if (!IsOpen()) 572 if (!IsOpen())
512 return ERR_UNEXPECTED; 573 return ERR_UNEXPECTED;
513 574
514 // We'd better be open for writing. 575 // We'd better be open for writing.
515 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 576 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
516 577
517 // Seek to the position to truncate from. 578 // Seek to the position to truncate from.
518 int64 seek_position = Seek(FROM_BEGIN, bytes); 579 int64 seek_position = SeekSync(FROM_BEGIN, bytes);
519 if (seek_position != bytes) 580 if (seek_position != bytes)
520 return ERR_UNEXPECTED; 581 return ERR_UNEXPECTED;
521 582
522 // And truncate the file. 583 // And truncate the file.
523 int result = ftruncate(file_, bytes); 584 int result = ftruncate(file_, bytes);
524 if (result == 0) 585 if (result == 0)
525 return seek_position; 586 return seek_position;
526 587
527 return RecordAndMapError(errno, 588 return RecordAndMapError(errno,
528 FILE_ERROR_SOURCE_SET_EOF, 589 FILE_ERROR_SOURCE_SET_EOF,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 net::NetLog::TYPE_FILE_STREAM_SOURCE, 623 net::NetLog::TYPE_FILE_STREAM_SOURCE,
563 make_scoped_refptr( 624 make_scoped_refptr(
564 new net::NetLogSourceParameter("source_dependency", 625 new net::NetLogSourceParameter("source_dependency",
565 bound_net_log_.source()))); 626 bound_net_log_.source())));
566 } 627 }
567 628
568 base::PlatformFile FileStreamPosix::GetPlatformFileForTesting() { 629 base::PlatformFile FileStreamPosix::GetPlatformFileForTesting() {
569 return file_; 630 return file_;
570 } 631 }
571 632
572 void FileStreamPosix::OnClosed() { 633 void FileStreamPosix::ResetOnIOComplete() {
573 file_ = base::kInvalidPlatformFileValue; 634 on_io_complete_.reset();
574 int result = OK; 635 weak_ptr_factory_.InvalidateWeakPtrs();
575 OnIOComplete(&result);
576 } 636 }
577 637
578 void FileStreamPosix::OnIOComplete(int* result) { 638 void FileStreamPosix::OnClosed(const CompletionCallback& callback) {
579 CompletionCallback temp_callback = callback_; 639 file_ = base::kInvalidPlatformFileValue;
580 callback_.Reset();
581 640
582 // Reset this before Run() as Run() may issue a new async operation. 641 // Reset this before Run() as Run() may issue a new async operation.
583 on_io_complete_.reset(); 642 ResetOnIOComplete();
584 temp_callback.Run(*result); 643 callback.Run(OK);
585 } 644 }
586 645
587 void FileStreamPosix::WaitForIOCompletion() { 646 void FileStreamPosix::WaitForIOCompletion() {
588 if (on_io_complete_.get()) { 647 if (on_io_complete_.get()) {
589 on_io_complete_->Wait(); 648 on_io_complete_->Wait();
590 on_io_complete_.reset(); 649 on_io_complete_.reset();
591 } 650 }
592 } 651 }
593 652
594 } // namespace net 653 } // namespace net
OLDNEW
« no previous file with comments | « net/base/file_stream_posix.h ('k') | net/base/file_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698