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

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, 4 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
« no previous file with comments | « net/base/file_stream.h ('k') | net/base/file_stream_posix.h » ('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 #include "base/threading/thread_restrictions.h"
5 #include "net/base/file_stream.h" 6 #include "net/base/file_stream.h"
willchan no longer on Chromium 2012/08/27 06:24:06 foo.h always goes first in foo.cc according to the
7 #if defined(OS_WIN)
willchan no longer on Chromium 2012/08/27 06:24:06 Anything with platform specific definitions goes a
pivanof 2012/08/27 08:43:31 I did exactly as you said initially but lint said
8 #include "net/base/file_stream_win.h"
9 #elif defined(OS_POSIX)
10 #include "net/base/file_stream_posix.h"
11 #endif
12 #include "net/base/net_errors.h"
6 13
7 namespace net { 14 namespace net {
8 15
9 FileStream::FileStream(net::NetLog* net_log) 16 FileStream::FileStream(net::NetLog* net_log)
10 : impl_(net_log) { 17 : context_(NULL),
11 } 18 open_flags_(0),
12 19 bound_net_log_(net::BoundNetLog::Make(net_log,
13 FileStream::FileStream( 20 net::NetLog::SOURCE_FILESTREAM)) {
14 base::PlatformFile file, int flags, net::NetLog* net_log) 21 context_ = new AsyncContext(bound_net_log_);
15 : impl_(file, flags, net_log) { 22
23 bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE);
24 }
25
26 FileStream::FileStream(base::PlatformFile file, int flags, net::NetLog* net_log)
27 : context_(NULL),
28 open_flags_(flags),
29 bound_net_log_(net::BoundNetLog::Make(net_log,
30 net::NetLog::SOURCE_FILESTREAM)) {
31 context_ = new AsyncContext(file, bound_net_log_, open_flags_);
32
33 bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE);
16 } 34 }
17 35
18 FileStream::~FileStream() { 36 FileStream::~FileStream() {
37 if (IsOpen() && !is_async())
38 CloseSync();
39 context_->Destroy();
40
41 bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE);
19 } 42 }
20 43
21 void FileStream::Close(const CompletionCallback& callback) { 44 void FileStream::Close(const CompletionCallback& callback) {
22 impl_.Close(callback); 45 DCHECK(is_async());
46 context_->CloseAsync(callback);
23 } 47 }
24 48
25 void FileStream::CloseSync() { 49 void FileStream::CloseSync() {
26 impl_.CloseSync(); 50 // CloseSync() should be called on the correct thread even if it eventually
51 // ends up inside CloseAndCancelAsync().
52 base::ThreadRestrictions::AssertIOAllowed();
53
54 // TODO(satorux): Replace the following async stuff with a
55 // DCHECK(is_async()) once all async clients are migrated to
56 // use Close(). crbug.com/114783
57 if (!context_->async_in_progress()) {
58 context_->CloseSync();
59 } else {
60 AsyncContext* old_ctx = context_;
61 context_ = new AsyncContext(bound_net_log_);
62 context_->set_record_uma(old_ctx->record_uma());
63 old_ctx->Destroy();
64 }
27 } 65 }
28 66
29 int FileStream::Open(const FilePath& path, int open_flags, 67 int FileStream::Open(const FilePath& path, int open_flags,
30 const CompletionCallback& callback) { 68 const CompletionCallback& callback) {
31 return impl_.Open(path, open_flags, callback); 69 if (IsOpen()) {
70 DLOG(FATAL) << "File is already open!";
71 return ERR_UNEXPECTED;
72 }
73
74 open_flags_ = open_flags;
75 DCHECK(is_async());
76 context_->OpenAsync(path, open_flags, callback);
77 return ERR_IO_PENDING;
32 } 78 }
33 79
34 int FileStream::OpenSync(const FilePath& path, int open_flags) { 80 int FileStream::OpenSync(const FilePath& path, int open_flags) {
35 return impl_.OpenSync(path, open_flags); 81 if (IsOpen()) {
82 DLOG(FATAL) << "File is already open!";
83 return ERR_UNEXPECTED;
84 }
85
86 open_flags_ = open_flags;
87 // TODO(satorux): Put a DCHECK once all async clients are migrated
88 // to use Open(). crbug.com/114783
89 //
90 // DCHECK(!is_async());
91 return context_->OpenSync(path, open_flags_);
36 } 92 }
37 93
38 bool FileStream::IsOpen() const { 94 bool FileStream::IsOpen() const {
39 return impl_.IsOpen(); 95 return context_->file() != base::kInvalidPlatformFileValue;
40 } 96 }
41 97
42 int FileStream::Seek(Whence whence, int64 offset, 98 int FileStream::Seek(Whence whence,
99 int64 offset,
43 const Int64CompletionCallback& callback) { 100 const Int64CompletionCallback& callback) {
44 return impl_.Seek(whence, offset, callback); 101 if (!IsOpen())
102 return ERR_UNEXPECTED;
103
104 // Make sure we're async.
105 DCHECK(is_async());
106 context_->SeekAsync(whence, offset, callback);
107 return ERR_IO_PENDING;
45 } 108 }
46 109
47 int64 FileStream::SeekSync(Whence whence, int64 offset) { 110 int64 FileStream::SeekSync(Whence whence, int64 offset) {
48 return impl_.SeekSync(whence, offset); 111 if (!IsOpen())
112 return ERR_UNEXPECTED;
113
114 // If we're in async, make sure we don't have a request in flight.
115 DCHECK(!is_async() || !context_->async_in_progress());
116 return context_->SeekSync(whence, offset);
49 } 117 }
50 118
51 int64 FileStream::Available() { 119 int64 FileStream::Available() {
52 return impl_.Available(); 120 base::ThreadRestrictions::AssertIOAllowed();
53 } 121
54 122 if (!IsOpen())
55 int FileStream::Read( 123 return ERR_UNEXPECTED;
56 IOBuffer* in_buf, int buf_len, const CompletionCallback& callback) { 124
57 return impl_.Read(in_buf, buf_len, callback); 125 int64 cur_pos = SeekSync(FROM_CURRENT, 0);
126 if (cur_pos < 0)
127 return cur_pos;
128
129 int64 size = context_->GetFileSize();
130 if (size < 0)
131 return size;
132
133 DCHECK_GT(size, cur_pos);
134 return size - cur_pos;
135 }
136
137 int FileStream::Read(IOBuffer* buf,
138 int buf_len,
139 const CompletionCallback& callback) {
140 if (!IsOpen())
141 return ERR_UNEXPECTED;
142
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 DCHECK(is_async());
147
148 return context_->ReadAsync(buf, buf_len, callback);
58 } 149 }
59 150
60 int FileStream::ReadSync(char* buf, int buf_len) { 151 int FileStream::ReadSync(char* buf, int buf_len) {
61 return impl_.ReadSync(buf, buf_len); 152 if (!IsOpen())
153 return ERR_UNEXPECTED;
154
155 DCHECK(!is_async());
156 // read(..., 0) will return 0, which indicates end-of-file.
157 DCHECK_GT(buf_len, 0);
158 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
159
160 return context_->ReadSync(buf, buf_len);
62 } 161 }
63 162
64 int FileStream::ReadUntilComplete(char *buf, int buf_len) { 163 int FileStream::ReadUntilComplete(char *buf, int buf_len) {
65 return impl_.ReadUntilComplete(buf, buf_len); 164 int to_read = buf_len;
66 } 165 int bytes_total = 0;
67 166
68 int FileStream::Write( 167 do {
69 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { 168 int bytes_read = ReadSync(buf, to_read);
70 return impl_.Write(buf, buf_len, callback); 169 if (bytes_read <= 0) {
170 if (bytes_total == 0)
171 return bytes_read;
172
173 return bytes_total;
174 }
175
176 bytes_total += bytes_read;
177 buf += bytes_read;
178 to_read -= bytes_read;
179 } while (bytes_total < buf_len);
180
181 return bytes_total;
182 }
183
184 int FileStream::Write(IOBuffer* buf,
185 int buf_len,
186 const CompletionCallback& callback) {
187 if (!IsOpen())
188 return ERR_UNEXPECTED;
189
190 DCHECK(is_async());
191 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
192 // write(..., 0) will return 0, which indicates end-of-file.
193 DCHECK_GT(buf_len, 0);
194
195 return context_->WriteAsync(buf, buf_len, callback);
71 } 196 }
72 197
73 int FileStream::WriteSync(const char* buf, int buf_len) { 198 int FileStream::WriteSync(const char* buf, int buf_len) {
74 return impl_.WriteSync(buf, buf_len); 199 if (!IsOpen())
200 return ERR_UNEXPECTED;
201
202 DCHECK(!is_async());
203 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
204 // write(..., 0) will return 0, which indicates end-of-file.
205 DCHECK_GT(buf_len, 0);
206
207 return context_->WriteSync(buf, buf_len);
75 } 208 }
76 209
77 int64 FileStream::Truncate(int64 bytes) { 210 int64 FileStream::Truncate(int64 bytes) {
78 return impl_.Truncate(bytes); 211 base::ThreadRestrictions::AssertIOAllowed();
212
213 if (!IsOpen())
214 return ERR_UNEXPECTED;
215
216 // We'd better be open for writing.
217 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
218
219 // Seek to the position to truncate from.
220 int64 seek_position = SeekSync(FROM_BEGIN, bytes);
221 if (seek_position != bytes)
222 return ERR_UNEXPECTED;
223
224 // And truncate the file.
225 return context_->Truncate(bytes);
79 } 226 }
80 227
81 int FileStream::Flush() { 228 int FileStream::Flush() {
82 return impl_.Flush(); 229 base::ThreadRestrictions::AssertIOAllowed();
230
231 if (!IsOpen())
232 return ERR_UNEXPECTED;
233
234 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
235 return context_->Flush();
83 } 236 }
84 237
85 void FileStream::EnableErrorStatistics() { 238 void FileStream::EnableErrorStatistics() {
86 impl_.EnableErrorStatistics(); 239 context_->set_record_uma(true);
87 } 240 }
88 241
89 void FileStream::SetBoundNetLogSource( 242 void FileStream::SetBoundNetLogSource(
90 const net::BoundNetLog& owner_bound_net_log) { 243 const net::BoundNetLog& owner_bound_net_log) {
91 impl_.SetBoundNetLogSource(owner_bound_net_log); 244 if ((owner_bound_net_log.source().id == net::NetLog::Source::kInvalidId) &&
245 (bound_net_log_.source().id == net::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(
254 net::NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER,
255 owner_bound_net_log.source().ToEventParametersCallback());
256
257 owner_bound_net_log.AddEvent(
258 net::NetLog::TYPE_FILE_STREAM_SOURCE,
259 bound_net_log_.source().ToEventParametersCallback());
92 } 260 }
93 261
94 base::PlatformFile FileStream::GetPlatformFileForTesting() { 262 base::PlatformFile FileStream::GetPlatformFileForTesting() {
95 return impl_.GetPlatformFileForTesting(); 263 return context_->file();
96 } 264 }
97 265
98 } // namespace net 266 } // namespace net
OLDNEW
« no previous file with comments | « net/base/file_stream.h ('k') | net/base/file_stream_posix.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698