Chromium Code Reviews| Index: net/base/file_stream_posix.cc |
| diff --git a/net/base/file_stream_posix.cc b/net/base/file_stream_posix.cc |
| index 6c9b13511ec3767c95873782f8fb86fe6d311306..eefabbfd932c31f1b4dc26d8c388719d337ee68c 100644 |
| --- a/net/base/file_stream_posix.cc |
| +++ b/net/base/file_stream_posix.cc |
| @@ -125,6 +125,37 @@ void CloseFileAndSignal(base::PlatformFile* file, |
| on_io_complete->Signal(); |
| } |
| +// Adjusts the position from where the data is read. |
| +void SeekFile(base::PlatformFile file, |
| + Whence whence, |
| + int64 offset, |
| + int64* result, |
| + bool record_uma, |
| + const net::BoundNetLog& bound_net_log) { |
| + off_t res = lseek(file, static_cast<off_t>(offset), |
| + static_cast<int>(whence)); |
| + if (res == static_cast<off_t>(-1)) { |
| + *result = RecordAndMapError(errno, |
| + FILE_ERROR_SOURCE_SEEK, |
| + record_uma, |
| + bound_net_log); |
| + return; |
| + } |
| + *result = res; |
| +} |
| + |
| +// Seeks a file by calling SeekSync() and signals the completion. |
| +void SeekFileAndSignal(base::PlatformFile file, |
| + Whence whence, |
| + int64 offset, |
| + int64* result, |
| + bool record_uma, |
| + base::WaitableEvent* on_io_complete, |
| + const net::BoundNetLog& bound_net_log) { |
| + SeekFile(file, whence, offset, result, record_uma, bound_net_log); |
| + on_io_complete->Signal(); |
| +} |
| + |
| // ReadFile() is a simple wrapper around read() that handles EINTR signals and |
| // calls MapSystemError() to map errno to net error codes. |
| void ReadFile(base::PlatformFile file, |
| @@ -203,6 +234,20 @@ int FlushFile(base::PlatformFile file, |
| return res; |
| } |
| +// Called when Read(), Write() or Seek() is completed. |
| +// |result| contains the result or a network error code. |
| +template <typename R> |
| +void OnIOComplete(const base::WeakPtr<FileStreamPosix>& stream, |
| + const base::Callback<void(R)>& callback, |
| + R* result) { |
| + if (!stream.get()) |
|
willchan no longer on Chromium
2012/04/05 15:12:28
You don't need this, base::Bind() will take care o
kinuko
2012/04/06 12:42:37
In this case stream is not a target object and I d
willchan no longer on Chromium
2012/04/09 12:33:57
Woops, totally misread that :)
|
| + return; |
| + |
| + // Reset this before Run() as Run() may issue a new async operation. |
| + stream->ResetOnIOComplete(); |
| + callback.Run(*result); |
| +} |
| + |
| } // namespace |
| // FileStreamPosix ------------------------------------------------------------ |
| @@ -257,9 +302,6 @@ FileStreamPosix::~FileStreamPosix() { |
| void FileStreamPosix::Close(const CompletionCallback& callback) { |
| DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); |
| - DCHECK(callback_.is_null()); |
|
willchan no longer on Chromium
2012/04/05 15:12:28
This DCHECK is useful. Let's keep it. It's basical
kinuko
2012/04/06 12:42:37
Done. I expect DCHECK(!on_io_complete_.get()) doe
|
| - |
| - callback_ = callback; |
| DCHECK(!on_io_complete_.get()); |
| on_io_complete_.reset(new base::WaitableEvent( |
| @@ -273,7 +315,8 @@ void FileStreamPosix::Close(const CompletionCallback& callback) { |
| base::Bind(&CloseFileAndSignal, &file_, on_io_complete_.get(), |
| bound_net_log_), |
| base::Bind(&FileStreamPosix::OnClosed, |
| - weak_ptr_factory_.GetWeakPtr()), |
| + weak_ptr_factory_.GetWeakPtr(), |
| + callback), |
| true /* task_is_slow */); |
| DCHECK(posted); |
| @@ -301,9 +344,6 @@ int FileStreamPosix::Open(const FilePath& path, int open_flags, |
| return ERR_UNEXPECTED; |
| } |
| - DCHECK(callback_.is_null()); |
| - callback_ = callback; |
| - |
| open_flags_ = open_flags; |
| DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); |
| @@ -320,9 +360,8 @@ int FileStreamPosix::Open(const FilePath& path, int open_flags, |
| base::Bind(&OpenFileAndSignal, |
| path, open_flags, record_uma_, &file_, result, |
| on_io_complete_.get(), bound_net_log_), |
| - base::Bind(&FileStreamPosix::OnIOComplete, |
| - weak_ptr_factory_.GetWeakPtr(), |
| - base::Owned(result)), |
| + base::Bind(&OnIOComplete<int>, weak_ptr_factory_.GetWeakPtr(), |
| + callback, base::Owned(result)), |
| true /* task_is_slow */); |
| DCHECK(posted); |
| return ERR_IO_PENDING; |
| @@ -349,7 +388,29 @@ bool FileStreamPosix::IsOpen() const { |
| return file_ != base::kInvalidPlatformFileValue; |
| } |
| -int64 FileStreamPosix::Seek(Whence whence, int64 offset) { |
| +int FileStreamPosix::Seek(Whence whence, int64 offset, |
| + const Int64CompletionCallback& callback) { |
| + if (!IsOpen()) |
| + return ERR_UNEXPECTED; |
| + |
| + // Make sure we're async. |
| + DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); |
| + |
| + int64* result = new int64(-1); |
| + DCHECK(!on_io_complete_.get()); |
| + const bool posted = base::WorkerPool::PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind(&SeekFileAndSignal, file_, whence, offset, result, |
| + record_uma_, on_io_complete_.get(), bound_net_log_), |
| + base::Bind(&OnIOComplete<int64>, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + callback, base::Owned(result)), |
| + true /* task is slow */); |
| + DCHECK(posted); |
| + return ERR_IO_PENDING; |
| +} |
| + |
| +int64 FileStreamPosix::SeekSync(Whence whence, int64 offset) { |
| base::ThreadRestrictions::AssertIOAllowed(); |
| if (!IsOpen()) |
| @@ -357,18 +418,11 @@ int64 FileStreamPosix::Seek(Whence whence, int64 offset) { |
| // If we're in async, make sure we don't have a request in flight. |
| DCHECK(!(open_flags_ & base::PLATFORM_FILE_ASYNC) || |
| - callback_.is_null()); |
| + !on_io_complete_.get()); |
| - off_t res = lseek(file_, static_cast<off_t>(offset), |
| - static_cast<int>(whence)); |
| - if (res == static_cast<off_t>(-1)) { |
| - return RecordAndMapError(errno, |
| - FILE_ERROR_SOURCE_SEEK, |
| - record_uma_, |
| - bound_net_log_); |
| - } |
| - |
| - return res; |
| + off_t result = -1; |
| + SeekFile(file_, whence, offset, &result, record_uma_, bound_net_log_); |
| + return result; |
| } |
| int64 FileStreamPosix::Available() { |
| @@ -377,7 +431,7 @@ int64 FileStreamPosix::Available() { |
| if (!IsOpen()) |
| return ERR_UNEXPECTED; |
| - int64 cur_pos = Seek(FROM_CURRENT, 0); |
| + int64 cur_pos = SeekSync(FROM_CURRENT, 0); |
| if (cur_pos < 0) |
| return cur_pos; |
| @@ -404,22 +458,21 @@ int FileStreamPosix::Read( |
| DCHECK_GT(buf_len, 0); |
| DCHECK(open_flags_ & base::PLATFORM_FILE_READ); |
| DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); |
| - // Make sure we don't have a request in flight. |
| - DCHECK(callback_.is_null()); |
| - callback_ = callback; |
| - int* result = new int(OK); |
| - scoped_refptr<IOBuffer> buf = in_buf; |
| + // Make sure we don't have a request in flight. |
| DCHECK(!on_io_complete_.get()); |
| on_io_complete_.reset(new base::WaitableEvent( |
| false /* manual_reset */, false /* initially_signaled */)); |
| + |
| + int* result = new int(OK); |
| + scoped_refptr<IOBuffer> buf = in_buf; |
| const bool posted = base::WorkerPool::PostTaskAndReply( |
| FROM_HERE, |
| base::Bind(&ReadFileAndSignal, file_, buf, buf_len, |
| record_uma_, result, on_io_complete_.get(), bound_net_log_), |
| - base::Bind(&FileStreamPosix::OnIOComplete, |
| + base::Bind(&OnIOComplete<int>, |
| weak_ptr_factory_.GetWeakPtr(), |
| - base::Owned(result)), |
| + callback, base::Owned(result)), |
| true /* task is slow */); |
| DCHECK(posted); |
| return ERR_IO_PENDING; |
| @@ -469,22 +522,21 @@ int FileStreamPosix::Write( |
| DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); |
| // write(..., 0) will return 0, which indicates end-of-file. |
| DCHECK_GT(buf_len, 0); |
| - // Make sure we don't have a request in flight. |
| - DCHECK(callback_.is_null()); |
| - callback_ = callback; |
| - int* result = new int(OK); |
| - scoped_refptr<IOBuffer> buf = in_buf; |
| + // Make sure we don't have a request in flight. |
| DCHECK(!on_io_complete_.get()); |
| on_io_complete_.reset(new base::WaitableEvent( |
| false /* manual_reset */, false /* initially_signaled */)); |
| + |
| + int* result = new int(OK); |
| + scoped_refptr<IOBuffer> buf = in_buf; |
| const bool posted = base::WorkerPool::PostTaskAndReply( |
| FROM_HERE, |
| base::Bind(&WriteFileAndSignal, file_, buf, buf_len, |
| record_uma_, result, on_io_complete_.get(), bound_net_log_), |
| - base::Bind(&FileStreamPosix::OnIOComplete, |
| + base::Bind(&OnIOComplete<int>, |
| weak_ptr_factory_.GetWeakPtr(), |
| - base::Owned(result)), |
| + callback, base::Owned(result)), |
| true /* task is slow */); |
| DCHECK(posted); |
| return ERR_IO_PENDING; |
| @@ -515,7 +567,7 @@ int64 FileStreamPosix::Truncate(int64 bytes) { |
| DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); |
| // Seek to the position to truncate from. |
| - int64 seek_position = Seek(FROM_BEGIN, bytes); |
| + int64 seek_position = SeekSync(FROM_BEGIN, bytes); |
| if (seek_position != bytes) |
| return ERR_UNEXPECTED; |
| @@ -569,19 +621,16 @@ base::PlatformFile FileStreamPosix::GetPlatformFileForTesting() { |
| return file_; |
| } |
| -void FileStreamPosix::OnClosed() { |
| - file_ = base::kInvalidPlatformFileValue; |
| - int result = OK; |
| - OnIOComplete(&result); |
| +void FileStreamPosix::ResetOnIOComplete() { |
|
willchan no longer on Chromium
2012/04/05 15:12:28
I'd invalidate weak pointers at the WeakPtrFactory
kinuko
2012/04/06 12:42:37
Good idea, added the invalidation and DCHECKs.
|
| + on_io_complete_.reset(); |
| } |
| -void FileStreamPosix::OnIOComplete(int* result) { |
| - CompletionCallback temp_callback = callback_; |
| - callback_.Reset(); |
| +void FileStreamPosix::OnClosed(const CompletionCallback& callback) { |
| + file_ = base::kInvalidPlatformFileValue; |
| // Reset this before Run() as Run() may issue a new async operation. |
| on_io_complete_.reset(); |
| - temp_callback.Run(*result); |
| + callback.Run(OK); |
| } |
| void FileStreamPosix::WaitForIOCompletion() { |