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

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

Issue 9288084: Added Net logging to FileStream. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Renamed BoundNetLog variables. Created 8 years, 10 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <windows.h> 7 #include <windows.h>
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
14 #include "net/base/file_stream_metrics.h" 14 #include "net/base/file_stream_metrics.h"
15 #include "net/base/file_stream_net_log_parameters.h"
15 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
16 17
17 namespace net { 18 namespace net {
18 19
19 // Ensure that we can just use our Whence values directly. 20 // Ensure that we can just use our Whence values directly.
20 COMPILE_ASSERT(FROM_BEGIN == FILE_BEGIN, bad_whence_begin); 21 COMPILE_ASSERT(FROM_BEGIN == FILE_BEGIN, bad_whence_begin);
21 COMPILE_ASSERT(FROM_CURRENT == FILE_CURRENT, bad_whence_current); 22 COMPILE_ASSERT(FROM_CURRENT == FILE_CURRENT, bad_whence_current);
22 COMPILE_ASSERT(FROM_END == FILE_END, bad_whence_end); 23 COMPILE_ASSERT(FROM_END == FILE_END, bad_whence_end);
23 24
24 static void SetOffset(OVERLAPPED* overlapped, const LARGE_INTEGER& offset) { 25 static void SetOffset(OVERLAPPED* overlapped, const LARGE_INTEGER& offset) {
25 overlapped->Offset = offset.LowPart; 26 overlapped->Offset = offset.LowPart;
26 overlapped->OffsetHigh = offset.HighPart; 27 overlapped->OffsetHigh = offset.HighPart;
27 } 28 }
28 29
29 static void IncrementOffset(OVERLAPPED* overlapped, DWORD count) { 30 static void IncrementOffset(OVERLAPPED* overlapped, DWORD count) {
30 LARGE_INTEGER offset; 31 LARGE_INTEGER offset;
31 offset.LowPart = overlapped->Offset; 32 offset.LowPart = overlapped->Offset;
32 offset.HighPart = overlapped->OffsetHigh; 33 offset.HighPart = overlapped->OffsetHigh;
33 offset.QuadPart += static_cast<LONGLONG>(count); 34 offset.QuadPart += static_cast<LONGLONG>(count);
34 SetOffset(overlapped, offset); 35 SetOffset(overlapped, offset);
35 } 36 }
36 37
37 namespace { 38 namespace {
38 39
39 int RecordAndMapError(int error, FileErrorSource source, bool record_uma) { 40 int RecordAndMapError(int error,
41 FileErrorSource source,
42 bool record_uma,
43 const net::BoundNetLog& log) {
44 log.AddEvent(net::NetLog::TYPE_FILE_STREAM_ERROR,
45 make_scoped_refptr(
46 new FileStreamErrorParameters(
47 GetFileErrorSourceName(source),
48 error)));
49
40 RecordFileError(error, source, record_uma); 50 RecordFileError(error, source, record_uma);
41 return MapSystemError(error); 51 return MapSystemError(error);
42 } 52 }
43 53
44 } // namespace 54 } // namespace
45 55
46 // FileStream::AsyncContext ---------------------------------------------- 56 // FileStream::AsyncContext ----------------------------------------------
47 57
48 class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { 58 class FileStream::AsyncContext : public MessageLoopForIO::IOHandler {
49 public: 59 public:
50 AsyncContext(FileStream* owner) 60 AsyncContext(FileStream* owner)
51 : owner_(owner), context_(), is_closing_(false), 61 : owner_(owner), context_(), is_closing_(false),
52 record_uma_(false), error_source_(FILE_ERROR_SOURCE_COUNT) { 62 record_uma_(false),
63 error_source_(FILE_ERROR_SOURCE_COUNT) {
53 context_.handler = this; 64 context_.handler = this;
54 } 65 }
55 ~AsyncContext(); 66 ~AsyncContext();
56 67
57 void IOCompletionIsPending(const CompletionCallback& callback); 68 void IOCompletionIsPending(const CompletionCallback& callback);
58 69
59 OVERLAPPED* overlapped() { return &context_.overlapped; } 70 OVERLAPPED* overlapped() { return &context_.overlapped; }
60 const CompletionCallback& callback() const { return callback_; } 71 const CompletionCallback& callback() const { return callback_; }
61 72
62 void set_error_source(FileErrorSource source) { error_source_ = source; } 73 void set_error_source(FileErrorSource source) { error_source_ = source; }
74 void set_bound_net_log(const net::BoundNetLog& log) { bound_net_log_ = log; }
mmenke 2012/01/30 22:38:39 nit: Suggest you use bound_net_log everywhere, to
ahendrickson 2012/01/31 20:12:41 Done.
63 75
64 void EnableErrorStatistics() { 76 void EnableErrorStatistics() {
65 record_uma_ = true; 77 record_uma_ = true;
66 } 78 }
67 79
68 private: 80 private:
69 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, 81 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context,
70 DWORD bytes_read, DWORD error); 82 DWORD bytes_read, DWORD error);
71 83
72 FileStream* owner_; 84 FileStream* owner_;
73 MessageLoopForIO::IOContext context_; 85 MessageLoopForIO::IOContext context_;
74 CompletionCallback callback_; 86 CompletionCallback callback_;
75 bool is_closing_; 87 bool is_closing_;
76 bool record_uma_; 88 bool record_uma_;
89 net::BoundNetLog bound_net_log_;
77 FileErrorSource error_source_; 90 FileErrorSource error_source_;
78 }; 91 };
79 92
80 FileStream::AsyncContext::~AsyncContext() { 93 FileStream::AsyncContext::~AsyncContext() {
81 is_closing_ = true; 94 is_closing_ = true;
82 bool waited = false; 95 bool waited = false;
83 base::TimeTicks start = base::TimeTicks::Now(); 96 base::TimeTicks start = base::TimeTicks::Now();
84 while (!callback_.is_null()) { 97 while (!callback_.is_null()) {
85 waited = true; 98 waited = true;
86 MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); 99 MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this);
(...skipping 15 matching lines...) Expand all
102 MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) { 115 MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) {
103 DCHECK_EQ(&context_, context); 116 DCHECK_EQ(&context_, context);
104 DCHECK(!callback_.is_null()); 117 DCHECK(!callback_.is_null());
105 118
106 if (is_closing_) { 119 if (is_closing_) {
107 callback_.Reset(); 120 callback_.Reset();
108 return; 121 return;
109 } 122 }
110 123
111 int result = static_cast<int>(bytes_read); 124 int result = static_cast<int>(bytes_read);
112 if (error && error != ERROR_HANDLE_EOF) 125 if (error && error != ERROR_HANDLE_EOF) {
113 result = RecordAndMapError(error, error_source_, record_uma_); 126 result = RecordAndMapError(error, error_source_, record_uma_,
127 bound_net_log_);
mmenke 2012/01/31 18:28:43 Any reason not to just get the bound net log from
Randy Smith (Not in Mondays) 2012/01/31 19:29:03 Sorry, Matt, confused by this comment and I'd like
ahendrickson 2012/01/31 20:12:41 Hmm, I suppose we could do that. However, there a
ahendrickson 2012/01/31 20:12:41 Randy, he means that the AsyncContext class can us
mmenke 2012/01/31 21:20:31 3 calls, actually. I don't feel that strongly abo
Randy Smith (Not in Mondays) 2012/01/31 22:22:41 Ah, that makes sense. As long as they only run on
ahendrickson 2012/01/31 22:29:47 Hmm, I like the constructor approach. In my origi
ahendrickson 2012/01/31 22:29:47 I'm not at all sure they run on the same thread.
Randy Smith (Not in Mondays) 2012/02/01 16:21:52 Now that I look more closely, it looks like Async
mmenke 2012/02/01 16:25:52 It's stored in a scoped_ptr owned by the stream, a
128 }
114 129
115 if (bytes_read) 130 if (bytes_read)
116 IncrementOffset(&context->overlapped, bytes_read); 131 IncrementOffset(&context->overlapped, bytes_read);
117 132
118 CompletionCallback temp; 133 CompletionCallback temp;
119 std::swap(temp, callback_); 134 std::swap(temp, callback_);
120 temp.Run(result); 135 temp.Run(result);
121 } 136 }
122 137
123 // FileStream ------------------------------------------------------------ 138 // FileStream ------------------------------------------------------------
124 139
125 FileStream::FileStream() 140 FileStream::FileStream()
126 : file_(INVALID_HANDLE_VALUE), 141 : file_(base::kInvalidPlatformFileValue),
127 open_flags_(0), 142 open_flags_(0),
128 auto_closed_(true), 143 auto_closed_(true),
129 record_uma_(false) { 144 record_uma_(false) {
130 } 145 }
131 146
147 FileStream::FileStream(net::NetLog* log)
148 : file_(base::kInvalidPlatformFileValue),
149 open_flags_(0),
150 auto_closed_(true),
151 record_uma_(false) {
152 bound_net_log_ = net::BoundNetLog::Make(log, net::NetLog::SOURCE_FILESTREAM);
153
154 bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL);
155 }
156
132 FileStream::FileStream(base::PlatformFile file, int flags) 157 FileStream::FileStream(base::PlatformFile file, int flags)
133 : file_(file), 158 : file_(file),
134 open_flags_(flags), 159 open_flags_(flags),
135 auto_closed_(false), 160 auto_closed_(false),
136 record_uma_(false) { 161 record_uma_(false) {
137 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to 162 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to
138 // make sure we will perform asynchronous File IO to it. 163 // make sure we will perform asynchronous File IO to it.
139 if (flags & base::PLATFORM_FILE_ASYNC) { 164 if (flags & base::PLATFORM_FILE_ASYNC) {
140 async_context_.reset(new AsyncContext(this)); 165 async_context_.reset(new AsyncContext(this));
141 MessageLoopForIO::current()->RegisterIOHandler(file_, 166 MessageLoopForIO::current()->RegisterIOHandler(file_,
142 async_context_.get()); 167 async_context_.get());
143 } 168 }
144 } 169 }
145 170
146 FileStream::~FileStream() { 171 FileStream::~FileStream() {
147 if (auto_closed_) 172 if (auto_closed_)
148 Close(); 173 Close();
174
175 bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL);
149 } 176 }
150 177
151 void FileStream::Close() { 178 void FileStream::Close() {
179 bound_net_log_.AddEvent(net::NetLog::TYPE_FILE_STREAM_CLOSE, NULL);
152 if (file_ != INVALID_HANDLE_VALUE) 180 if (file_ != INVALID_HANDLE_VALUE)
153 CancelIo(file_); 181 CancelIo(file_);
154 182
155 async_context_.reset(); 183 async_context_.reset();
156 if (file_ != INVALID_HANDLE_VALUE) { 184 if (file_ != INVALID_HANDLE_VALUE) {
157 CloseHandle(file_); 185 CloseHandle(file_);
158 file_ = INVALID_HANDLE_VALUE; 186 file_ = INVALID_HANDLE_VALUE;
187
188 bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_OPEN, NULL);
159 } 189 }
160 } 190 }
161 191
162 int FileStream::Open(const FilePath& path, int open_flags) { 192 int FileStream::Open(const FilePath& path, int open_flags) {
193 bound_net_log_.BeginEvent(
194 net::NetLog::TYPE_FILE_STREAM_OPEN,
195 make_scoped_refptr(
196 new net::NetLogStringParameter("file_name",
197 path.AsUTF8Unsafe())));
198
163 if (IsOpen()) { 199 if (IsOpen()) {
164 DLOG(FATAL) << "File is already open!"; 200 DLOG(FATAL) << "File is already open!";
165 return ERR_UNEXPECTED; 201 return ERR_UNEXPECTED;
166 } 202 }
167 203
168 open_flags_ = open_flags; 204 open_flags_ = open_flags;
169 file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); 205 file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL);
170 if (file_ == INVALID_HANDLE_VALUE) { 206 if (file_ == INVALID_HANDLE_VALUE) {
171 DWORD error = GetLastError(); 207 DWORD error = GetLastError();
172 LOG(WARNING) << "Failed to open file: " << error; 208 LOG(WARNING) << "Failed to open file: " << error;
173 return RecordAndMapError(error, FILE_ERROR_SOURCE_OPEN, record_uma_); 209 return RecordAndMapError(error,
210 FILE_ERROR_SOURCE_OPEN,
211 record_uma_,
212 bound_net_log_);
174 } 213 }
175 214
176 if (open_flags_ & base::PLATFORM_FILE_ASYNC) { 215 if (open_flags_ & base::PLATFORM_FILE_ASYNC) {
177 async_context_.reset(new AsyncContext(this)); 216 async_context_.reset(new AsyncContext(this));
178 if (record_uma_) 217 if (record_uma_)
179 async_context_->EnableErrorStatistics(); 218 async_context_->EnableErrorStatistics();
180 MessageLoopForIO::current()->RegisterIOHandler(file_, 219 MessageLoopForIO::current()->RegisterIOHandler(file_,
181 async_context_.get()); 220 async_context_.get());
182 } 221 }
183 222
184 return OK; 223 return OK;
185 } 224 }
186 225
187 bool FileStream::IsOpen() const { 226 bool FileStream::IsOpen() const {
188 return file_ != INVALID_HANDLE_VALUE; 227 return file_ != INVALID_HANDLE_VALUE;
189 } 228 }
190 229
191 int64 FileStream::Seek(Whence whence, int64 offset) { 230 int64 FileStream::Seek(Whence whence, int64 offset) {
192 if (!IsOpen()) 231 if (!IsOpen())
193 return ERR_UNEXPECTED; 232 return ERR_UNEXPECTED;
194 233
195 DCHECK(!async_context_.get() || async_context_->callback().is_null()); 234 DCHECK(!async_context_.get() || async_context_->callback().is_null());
196 235
197 LARGE_INTEGER distance, result; 236 LARGE_INTEGER distance, result;
198 distance.QuadPart = offset; 237 distance.QuadPart = offset;
199 DWORD move_method = static_cast<DWORD>(whence); 238 DWORD move_method = static_cast<DWORD>(whence);
200 if (!SetFilePointerEx(file_, distance, &result, move_method)) { 239 if (!SetFilePointerEx(file_, distance, &result, move_method)) {
201 DWORD error = GetLastError(); 240 DWORD error = GetLastError();
202 LOG(WARNING) << "SetFilePointerEx failed: " << error; 241 LOG(WARNING) << "SetFilePointerEx failed: " << error;
203 return RecordAndMapError(error, FILE_ERROR_SOURCE_SEEK, record_uma_); 242 return RecordAndMapError(error,
243 FILE_ERROR_SOURCE_SEEK,
244 record_uma_,
245 bound_net_log_);
204 } 246 }
205 if (async_context_.get()) { 247 if (async_context_.get()) {
206 async_context_->set_error_source(FILE_ERROR_SOURCE_SEEK); 248 async_context_->set_error_source(FILE_ERROR_SOURCE_SEEK);
249 async_context_->set_bound_net_log(bound_net_log_);
207 SetOffset(async_context_->overlapped(), result); 250 SetOffset(async_context_->overlapped(), result);
208 } 251 }
209 return result.QuadPart; 252 return result.QuadPart;
210 } 253 }
211 254
212 int64 FileStream::Available() { 255 int64 FileStream::Available() {
213 base::ThreadRestrictions::AssertIOAllowed(); 256 base::ThreadRestrictions::AssertIOAllowed();
214 257
215 if (!IsOpen()) 258 if (!IsOpen())
216 return ERR_UNEXPECTED; 259 return ERR_UNEXPECTED;
217 260
218 int64 cur_pos = Seek(FROM_CURRENT, 0); 261 int64 cur_pos = Seek(FROM_CURRENT, 0);
219 if (cur_pos < 0) 262 if (cur_pos < 0)
220 return cur_pos; 263 return cur_pos;
221 264
222 LARGE_INTEGER file_size; 265 LARGE_INTEGER file_size;
223 if (!GetFileSizeEx(file_, &file_size)) { 266 if (!GetFileSizeEx(file_, &file_size)) {
224 DWORD error = GetLastError(); 267 DWORD error = GetLastError();
225 LOG(WARNING) << "GetFileSizeEx failed: " << error; 268 LOG(WARNING) << "GetFileSizeEx failed: " << error;
226 return RecordAndMapError(error, FILE_ERROR_SOURCE_GET_SIZE, record_uma_); 269 return RecordAndMapError(error,
270 FILE_ERROR_SOURCE_GET_SIZE,
271 record_uma_,
272 bound_net_log_);
227 } 273 }
228 274
229 return file_size.QuadPart - cur_pos; 275 return file_size.QuadPart - cur_pos;
230 } 276 }
231 277
232 int FileStream::Read( 278 int FileStream::Read(
233 char* buf, int buf_len, const CompletionCallback& callback) { 279 char* buf, int buf_len, const CompletionCallback& callback) {
234 if (!IsOpen()) 280 if (!IsOpen())
235 return ERR_UNEXPECTED; 281 return ERR_UNEXPECTED;
236 282
237 DCHECK(open_flags_ & base::PLATFORM_FILE_READ); 283 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
238 284
239 OVERLAPPED* overlapped = NULL; 285 OVERLAPPED* overlapped = NULL;
240 if (async_context_.get()) { 286 if (async_context_.get()) {
241 DCHECK(!callback.is_null()); 287 DCHECK(!callback.is_null());
242 DCHECK(async_context_->callback().is_null()); 288 DCHECK(async_context_->callback().is_null());
243 overlapped = async_context_->overlapped(); 289 overlapped = async_context_->overlapped();
244 async_context_->set_error_source(FILE_ERROR_SOURCE_READ); 290 async_context_->set_error_source(FILE_ERROR_SOURCE_READ);
291 async_context_->set_bound_net_log(bound_net_log_);
245 } else { 292 } else {
246 DCHECK(callback.is_null()); 293 DCHECK(callback.is_null());
247 base::ThreadRestrictions::AssertIOAllowed(); 294 base::ThreadRestrictions::AssertIOAllowed();
248 } 295 }
249 296
250 int rv; 297 int rv;
251 298
252 DWORD bytes_read; 299 DWORD bytes_read;
253 if (!ReadFile(file_, buf, buf_len, &bytes_read, overlapped)) { 300 if (!ReadFile(file_, buf, buf_len, &bytes_read, overlapped)) {
254 DWORD error = GetLastError(); 301 DWORD error = GetLastError();
255 if (async_context_.get() && error == ERROR_IO_PENDING) { 302 if (async_context_.get() && error == ERROR_IO_PENDING) {
256 async_context_->IOCompletionIsPending(callback); 303 async_context_->IOCompletionIsPending(callback);
257 rv = ERR_IO_PENDING; 304 rv = ERR_IO_PENDING;
258 } else if (error == ERROR_HANDLE_EOF) { 305 } else if (error == ERROR_HANDLE_EOF) {
259 rv = 0; // Report EOF by returning 0 bytes read. 306 rv = 0; // Report EOF by returning 0 bytes read.
260 } else { 307 } else {
261 LOG(WARNING) << "ReadFile failed: " << error; 308 LOG(WARNING) << "ReadFile failed: " << error;
262 rv = RecordAndMapError(error, FILE_ERROR_SOURCE_READ, record_uma_); 309 rv = RecordAndMapError(error,
310 FILE_ERROR_SOURCE_READ,
311 record_uma_,
312 bound_net_log_);
263 } 313 }
264 } else if (overlapped) { 314 } else if (overlapped) {
265 async_context_->IOCompletionIsPending(callback); 315 async_context_->IOCompletionIsPending(callback);
266 rv = ERR_IO_PENDING; 316 rv = ERR_IO_PENDING;
267 } else { 317 } else {
268 rv = static_cast<int>(bytes_read); 318 rv = static_cast<int>(bytes_read);
269 } 319 }
270 return rv; 320 return rv;
271 } 321 }
272 322
(...skipping 24 matching lines...) Expand all
297 return ERR_UNEXPECTED; 347 return ERR_UNEXPECTED;
298 348
299 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 349 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
300 350
301 OVERLAPPED* overlapped = NULL; 351 OVERLAPPED* overlapped = NULL;
302 if (async_context_.get()) { 352 if (async_context_.get()) {
303 DCHECK(!callback.is_null()); 353 DCHECK(!callback.is_null());
304 DCHECK(async_context_->callback().is_null()); 354 DCHECK(async_context_->callback().is_null());
305 overlapped = async_context_->overlapped(); 355 overlapped = async_context_->overlapped();
306 async_context_->set_error_source(FILE_ERROR_SOURCE_WRITE); 356 async_context_->set_error_source(FILE_ERROR_SOURCE_WRITE);
357 async_context_->set_bound_net_log(bound_net_log_);
307 } else { 358 } else {
308 DCHECK(callback.is_null()); 359 DCHECK(callback.is_null());
309 base::ThreadRestrictions::AssertIOAllowed(); 360 base::ThreadRestrictions::AssertIOAllowed();
310 } 361 }
311 362
312 int rv; 363 int rv;
313 DWORD bytes_written; 364 DWORD bytes_written;
314 if (!WriteFile(file_, buf, buf_len, &bytes_written, overlapped)) { 365 if (!WriteFile(file_, buf, buf_len, &bytes_written, overlapped)) {
315 DWORD error = GetLastError(); 366 DWORD error = GetLastError();
316 if (async_context_.get() && error == ERROR_IO_PENDING) { 367 if (async_context_.get() && error == ERROR_IO_PENDING) {
317 async_context_->IOCompletionIsPending(callback); 368 async_context_->IOCompletionIsPending(callback);
318 rv = ERR_IO_PENDING; 369 rv = ERR_IO_PENDING;
319 } else { 370 } else {
320 LOG(WARNING) << "WriteFile failed: " << error; 371 LOG(WARNING) << "WriteFile failed: " << error;
321 rv = RecordAndMapError(error, FILE_ERROR_SOURCE_WRITE, record_uma_); 372 rv = RecordAndMapError(error,
373 FILE_ERROR_SOURCE_WRITE,
374 record_uma_,
375 bound_net_log_);
322 } 376 }
323 } else if (overlapped) { 377 } else if (overlapped) {
324 async_context_->IOCompletionIsPending(callback); 378 async_context_->IOCompletionIsPending(callback);
325 rv = ERR_IO_PENDING; 379 rv = ERR_IO_PENDING;
326 } else { 380 } else {
327 rv = static_cast<int>(bytes_written); 381 rv = static_cast<int>(bytes_written);
328 } 382 }
329 return rv; 383 return rv;
330 } 384 }
331 385
332 int FileStream::Flush() { 386 int FileStream::Flush() {
333 base::ThreadRestrictions::AssertIOAllowed(); 387 base::ThreadRestrictions::AssertIOAllowed();
334 388
335 if (!IsOpen()) 389 if (!IsOpen())
336 return ERR_UNEXPECTED; 390 return ERR_UNEXPECTED;
337 391
338 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 392 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
339 if (FlushFileBuffers(file_)) { 393 if (FlushFileBuffers(file_)) {
340 return OK; 394 return OK;
341 } 395 }
342 396
343 return RecordAndMapError(GetLastError(), 397 return RecordAndMapError(GetLastError(),
344 FILE_ERROR_SOURCE_FLUSH, 398 FILE_ERROR_SOURCE_FLUSH,
345 record_uma_); 399 record_uma_,
400 bound_net_log_);
346 } 401 }
347 402
348 int64 FileStream::Truncate(int64 bytes) { 403 int64 FileStream::Truncate(int64 bytes) {
349 base::ThreadRestrictions::AssertIOAllowed(); 404 base::ThreadRestrictions::AssertIOAllowed();
350 405
351 if (!IsOpen()) 406 if (!IsOpen())
352 return ERR_UNEXPECTED; 407 return ERR_UNEXPECTED;
353 408
354 // We better be open for reading. 409 // We'd better be open for reading.
mmenke 2012/01/31 18:28:43 Sorry, wasn't clear with my original comment. Tha
ahendrickson 2012/01/31 20:12:41 Done.
355 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 410 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
356 411
357 // Seek to the position to truncate from. 412 // Seek to the position to truncate from.
358 int64 seek_position = Seek(FROM_BEGIN, bytes); 413 int64 seek_position = Seek(FROM_BEGIN, bytes);
359 if (seek_position != bytes) 414 if (seek_position != bytes)
360 return ERR_UNEXPECTED; 415 return ERR_UNEXPECTED;
361 416
362 // And truncate the file. 417 // And truncate the file.
363 BOOL result = SetEndOfFile(file_); 418 BOOL result = SetEndOfFile(file_);
364 if (!result) { 419 if (!result) {
365 DWORD error = GetLastError(); 420 DWORD error = GetLastError();
366 LOG(WARNING) << "SetEndOfFile failed: " << error; 421 LOG(WARNING) << "SetEndOfFile failed: " << error;
367 return RecordAndMapError(error, FILE_ERROR_SOURCE_SET_EOF, record_uma_); 422 return RecordAndMapError(error,
423 FILE_ERROR_SOURCE_SET_EOF,
424 record_uma_,
425 bound_net_log_);
368 } 426 }
369 427
370 // Success. 428 // Success.
371 return seek_position; 429 return seek_position;
372 } 430 }
373 431
374 void FileStream::EnableErrorStatistics() { 432 void FileStream::EnableErrorStatistics() {
375 record_uma_ = true; 433 record_uma_ = true;
376 434
377 if (async_context_.get()) 435 if (async_context_.get())
378 async_context_->EnableErrorStatistics(); 436 async_context_->EnableErrorStatistics();
379 } 437 }
380 438
439 void FileStream::SetBoundNetLogSource(const net::BoundNetLog& log) {
440 if (log.source().id == net::NetLog::Source::kInvalidId)
441 return;
442
443 if (log.source().id == bound_net_log_.source().id)
444 return;
445
446 bound_net_log_.AddEvent(
447 net::NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER,
448 make_scoped_refptr(
449 new net::NetLogSourceParameter("source_dependency",
450 log.source())));
451
452 log.AddEvent(
453 net::NetLog::TYPE_FILE_STREAM_SOURCE,
454 make_scoped_refptr(
455 new net::NetLogSourceParameter("source_dependency",
456 bound_net_log_.source())));
457 }
458
381 } // namespace net 459 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698