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

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

Issue 10701050: net: Implement canceling of all async operations in FileStream. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 1 month 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
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.h" 5 #include "net/base/file_stream.h"
6 6
7 #include "base/location.h"
8 #include "base/message_loop_proxy.h"
9 #include "base/task_runner_util.h"
10 #include "base/threading/thread_restrictions.h"
11 #include "base/threading/worker_pool.h"
12 #include "net/base/file_stream_context.h"
13 #include "net/base/file_stream_net_log_parameters.h"
14 #include "net/base/net_errors.h"
15
7 namespace net { 16 namespace net {
8 17
9 FileStream::FileStream(net::NetLog* net_log) 18 FileStream::FileStream(NetLog* net_log)
10 : impl_(net_log) { 19 /* To allow never opened stream to be destroyed on any thread we set flags
11 } 20 as if stream was opened asynchronously. */
12 21 : open_flags_(base::PLATFORM_FILE_ASYNC),
13 FileStream::FileStream( 22 bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
14 base::PlatformFile file, int flags, net::NetLog* net_log) 23 context_(new Context(bound_net_log_)) {
15 : impl_(file, flags, net_log) { 24 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
25 }
26
27 FileStream::FileStream(base::PlatformFile file, int flags, NetLog* net_log)
28 : open_flags_(flags),
29 bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
30 context_(new Context(file, bound_net_log_, open_flags_)) {
31 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
16 } 32 }
17 33
18 FileStream::~FileStream() { 34 FileStream::~FileStream() {
19 } 35 if (!is_async()) {
20 36 base::ThreadRestrictions::AssertIOAllowed();
21 void FileStream::Close(const CompletionCallback& callback) { 37 context_->CloseSync();
22 impl_.Close(callback); 38 context_.reset();
23 } 39 } else {
24 40 context_.release()->Orphan();
25 void FileStream::CloseSync() { 41 }
26 impl_.CloseSync(); 42
43 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
27 } 44 }
28 45
29 int FileStream::Open(const FilePath& path, int open_flags, 46 int FileStream::Open(const FilePath& path, int open_flags,
30 const CompletionCallback& callback) { 47 const CompletionCallback& callback) {
31 return impl_.Open(path, open_flags, callback); 48 if (IsOpen()) {
49 DLOG(FATAL) << "File is already open!";
50 return ERR_UNEXPECTED;
51 }
52
53 open_flags_ = open_flags;
54 DCHECK(is_async());
55 context_->OpenAsync(path, open_flags, callback);
56 return ERR_IO_PENDING;
32 } 57 }
33 58
34 int FileStream::OpenSync(const FilePath& path, int open_flags) { 59 int FileStream::OpenSync(const FilePath& path, int open_flags) {
35 return impl_.OpenSync(path, open_flags); 60 base::ThreadRestrictions::AssertIOAllowed();
61
62 if (IsOpen()) {
63 DLOG(FATAL) << "File is already open!";
64 return ERR_UNEXPECTED;
65 }
66
67 open_flags_ = open_flags;
68 // TODO(satorux): Put a DCHECK once all async clients are migrated
69 // to use Open(). crbug.com/114783
70 //
71 // DCHECK(!is_async());
72 return context_->OpenSync(path, open_flags_);
36 } 73 }
37 74
38 bool FileStream::IsOpen() const { 75 bool FileStream::IsOpen() const {
39 return impl_.IsOpen(); 76 return context_->file() != base::kInvalidPlatformFileValue;
40 } 77 }
41 78
42 int FileStream::Seek(Whence whence, int64 offset, 79 int FileStream::Seek(Whence whence,
80 int64 offset,
43 const Int64CompletionCallback& callback) { 81 const Int64CompletionCallback& callback) {
44 return impl_.Seek(whence, offset, callback); 82 if (!IsOpen())
83 return ERR_UNEXPECTED;
84
85 // Make sure we're async.
86 DCHECK(is_async());
87 context_->SeekAsync(whence, offset, callback);
88 return ERR_IO_PENDING;
45 } 89 }
46 90
47 int64 FileStream::SeekSync(Whence whence, int64 offset) { 91 int64 FileStream::SeekSync(Whence whence, int64 offset) {
48 return impl_.SeekSync(whence, offset); 92 base::ThreadRestrictions::AssertIOAllowed();
93
94 if (!IsOpen())
95 return ERR_UNEXPECTED;
96
97 // If we're in async, make sure we don't have a request in flight.
98 DCHECK(!is_async() || !context_->async_in_progress());
99 return context_->SeekSync(whence, offset);
49 } 100 }
50 101
51 int64 FileStream::Available() { 102 int64 FileStream::Available() {
52 return impl_.Available(); 103 base::ThreadRestrictions::AssertIOAllowed();
53 } 104
54 105 if (!IsOpen())
55 int FileStream::Read( 106 return ERR_UNEXPECTED;
56 IOBuffer* in_buf, int buf_len, const CompletionCallback& callback) { 107
57 return impl_.Read(in_buf, buf_len, callback); 108 int64 cur_pos = SeekSync(FROM_CURRENT, 0);
109 if (cur_pos < 0)
110 return cur_pos;
111
112 int64 size = context_->GetFileSize();
113 if (size < 0)
114 return size;
115
116 DCHECK_GT(size, cur_pos);
117 return size - cur_pos;
118 }
119
120 int FileStream::Read(IOBuffer* buf,
121 int buf_len,
122 const CompletionCallback& callback) {
123 if (!IsOpen())
124 return ERR_UNEXPECTED;
125
126 // read(..., 0) will return 0, which indicates end-of-file.
127 DCHECK_GT(buf_len, 0);
128 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
129 DCHECK(is_async());
130
131 return context_->ReadAsync(buf, buf_len, callback);
58 } 132 }
59 133
60 int FileStream::ReadSync(char* buf, int buf_len) { 134 int FileStream::ReadSync(char* buf, int buf_len) {
61 return impl_.ReadSync(buf, buf_len); 135 base::ThreadRestrictions::AssertIOAllowed();
136
137 if (!IsOpen())
138 return ERR_UNEXPECTED;
139
140 DCHECK(!is_async());
141 // read(..., 0) will return 0, which indicates end-of-file.
142 DCHECK_GT(buf_len, 0);
143 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
144
145 return context_->ReadSync(buf, buf_len);
62 } 146 }
63 147
64 int FileStream::ReadUntilComplete(char *buf, int buf_len) { 148 int FileStream::ReadUntilComplete(char *buf, int buf_len) {
65 return impl_.ReadUntilComplete(buf, buf_len); 149 base::ThreadRestrictions::AssertIOAllowed();
66 } 150
67 151 int to_read = buf_len;
68 int FileStream::Write( 152 int bytes_total = 0;
69 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { 153
70 return impl_.Write(buf, buf_len, callback); 154 do {
155 int bytes_read = ReadSync(buf, to_read);
156 if (bytes_read <= 0) {
157 if (bytes_total == 0)
158 return bytes_read;
159
160 return bytes_total;
161 }
162
163 bytes_total += bytes_read;
164 buf += bytes_read;
165 to_read -= bytes_read;
166 } while (bytes_total < buf_len);
167
168 return bytes_total;
169 }
170
171 int FileStream::Write(IOBuffer* buf,
172 int buf_len,
173 const CompletionCallback& callback) {
174 if (!IsOpen())
175 return ERR_UNEXPECTED;
176
177 DCHECK(is_async());
178 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
179 // write(..., 0) will return 0, which indicates end-of-file.
180 DCHECK_GT(buf_len, 0);
181
182 return context_->WriteAsync(buf, buf_len, callback);
71 } 183 }
72 184
73 int FileStream::WriteSync(const char* buf, int buf_len) { 185 int FileStream::WriteSync(const char* buf, int buf_len) {
74 return impl_.WriteSync(buf, buf_len); 186 base::ThreadRestrictions::AssertIOAllowed();
187
188 if (!IsOpen())
189 return ERR_UNEXPECTED;
190
191 DCHECK(!is_async());
192 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
193 // write(..., 0) will return 0, which indicates end-of-file.
194 DCHECK_GT(buf_len, 0);
195
196 return context_->WriteSync(buf, buf_len);
75 } 197 }
76 198
77 int64 FileStream::Truncate(int64 bytes) { 199 int64 FileStream::Truncate(int64 bytes) {
78 return impl_.Truncate(bytes); 200 base::ThreadRestrictions::AssertIOAllowed();
201
202 if (!IsOpen())
203 return ERR_UNEXPECTED;
204
205 // We'd better be open for writing.
206 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
207
208 // Seek to the position to truncate from.
209 int64 seek_position = SeekSync(FROM_BEGIN, bytes);
210 if (seek_position != bytes)
211 return ERR_UNEXPECTED;
212
213 // And truncate the file.
214 return context_->Truncate(bytes);
79 } 215 }
80 216
81 int FileStream::Flush(const CompletionCallback& callback) { 217 int FileStream::Flush(const CompletionCallback& callback) {
82 return impl_.Flush(callback); 218 if (!IsOpen())
219 return ERR_UNEXPECTED;
220
221 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
222 // Make sure we're async.
223 DCHECK(is_async());
224
225 context_->FlushAsync(callback);
226 return ERR_IO_PENDING;
83 } 227 }
84 228
85 int FileStream::FlushSync() { 229 int FileStream::FlushSync() {
86 return impl_.FlushSync(); 230 base::ThreadRestrictions::AssertIOAllowed();
231
232 if (!IsOpen())
233 return ERR_UNEXPECTED;
234
235 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
236 return context_->FlushSync();
87 } 237 }
88 238
89 void FileStream::EnableErrorStatistics() { 239 void FileStream::EnableErrorStatistics() {
90 impl_.EnableErrorStatistics(); 240 context_->set_record_uma(true);
91 } 241 }
92 242
93 void FileStream::SetBoundNetLogSource( 243 void FileStream::SetBoundNetLogSource(const BoundNetLog& owner_bound_net_log) {
94 const net::BoundNetLog& owner_bound_net_log) { 244 if ((owner_bound_net_log.source().id == NetLog::Source::kInvalidId) &&
95 impl_.SetBoundNetLogSource(owner_bound_net_log); 245 (bound_net_log_.source().id == NetLog::Source::kInvalidId)) {
246 // Both |BoundNetLog|s are invalid.
247 return;
248 }
249
250 // Should never connect to itself.
251 DCHECK_NE(bound_net_log_.source().id, owner_bound_net_log.source().id);
252
253 bound_net_log_.AddEvent(NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER,
254 owner_bound_net_log.source().ToEventParametersCallback());
255
256 owner_bound_net_log.AddEvent(NetLog::TYPE_FILE_STREAM_SOURCE,
257 bound_net_log_.source().ToEventParametersCallback());
96 } 258 }
97 259
98 base::PlatformFile FileStream::GetPlatformFileForTesting() { 260 base::PlatformFile FileStream::GetPlatformFileForTesting() {
99 return impl_.GetPlatformFileForTesting(); 261 return context_->file();
100 } 262 }
101 263
102 } // namespace net 264 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698