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

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

Powered by Google App Engine
This is Rietveld 408576698