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

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

Issue 7583049: Record UMA statistics for file_stream operations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Hopefully fixed crash bug in file stream UMA stats. Created 9 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 | Annotate | Revision Log
« no previous file with comments | « net/base/file_stream.cc ('k') | net/base/file_stream_win.cc » ('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) 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 // For 64-bit file access (off_t = off64_t, lseek64, etc). 5 // For 64-bit file access (off_t = off64_t, lseek64, etc).
6 #define _FILE_OFFSET_BITS 64 6 #define _FILE_OFFSET_BITS 64
7 7
8 #include "net/base/file_stream.h" 8 #include "net/base/file_stream.h"
9 9
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 case EACCES: 55 case EACCES:
56 return ERR_ACCESS_DENIED; 56 return ERR_ACCESS_DENIED;
57 default: 57 default:
58 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; 58 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
59 return ERR_FAILED; 59 return ERR_FAILED;
60 } 60 }
61 } 61 }
62 62
63 // ReadFile() is a simple wrapper around read() that handles EINTR signals and 63 // ReadFile() is a simple wrapper around read() that handles EINTR signals and
64 // calls MapErrorCode() to map errno to net error codes. 64 // calls MapErrorCode() to map errno to net error codes.
65 int ReadFile(base::PlatformFile file, char* buf, int buf_len) { 65 int ReadFile(base::PlatformFile file, char* buf, int buf_len, int class_flags) {
66 base::ThreadRestrictions::AssertIOAllowed(); 66 base::ThreadRestrictions::AssertIOAllowed();
67 // read(..., 0) returns 0 to indicate end-of-file. 67 // read(..., 0) returns 0 to indicate end-of-file.
68 68
69 // Loop in the case of getting interrupted by a signal. 69 // Loop in the case of getting interrupted by a signal.
70 ssize_t res = HANDLE_EINTR(read(file, buf, static_cast<size_t>(buf_len))); 70 ssize_t res = HANDLE_EINTR(read(file, buf, static_cast<size_t>(buf_len)));
71 if (res == static_cast<ssize_t>(-1)) 71 if (res == static_cast<ssize_t>(-1)) {
72 return MapErrorCode(errno); 72 int error = errno;
73 RecordFileError(error, FILE_ERROR_TYPES_READ, class_flags);
74 return MapErrorCode(error);
75 }
73 return static_cast<int>(res); 76 return static_cast<int>(res);
74 } 77 }
75 78
76 void ReadFileTask(base::PlatformFile file, 79 void ReadFileTask(base::PlatformFile file,
77 char* buf, 80 char* buf,
78 int buf_len, 81 int buf_len,
82 int class_flags,
79 CompletionCallback* callback) { 83 CompletionCallback* callback) {
80 callback->Run(ReadFile(file, buf, buf_len)); 84 callback->Run(ReadFile(file, buf, buf_len, class_flags));
81 } 85 }
82 86
83 // WriteFile() is a simple wrapper around write() that handles EINTR signals and 87 // WriteFile() is a simple wrapper around write() that handles EINTR signals and
84 // calls MapErrorCode() to map errno to net error codes. It tries to write to 88 // calls MapErrorCode() to map errno to net error codes. It tries to write to
85 // completion. 89 // completion.
86 int WriteFile(base::PlatformFile file, const char* buf, int buf_len) { 90 int WriteFile(base::PlatformFile file, const char* buf, int buf_len,
91 int class_flags) {
87 base::ThreadRestrictions::AssertIOAllowed(); 92 base::ThreadRestrictions::AssertIOAllowed();
88 ssize_t res = HANDLE_EINTR(write(file, buf, buf_len)); 93 ssize_t res = HANDLE_EINTR(write(file, buf, buf_len));
89 if (res == -1) 94 if (res == -1) {
90 return MapErrorCode(errno); 95 int error = errno;
96 RecordFileError(error, FILE_ERROR_TYPES_WRITE, class_flags);
97 return MapErrorCode(error);
98 }
91 return res; 99 return res;
92 } 100 }
93 101
94 void WriteFileTask(base::PlatformFile file, 102 void WriteFileTask(base::PlatformFile file,
95 const char* buf, 103 const char* buf,
96 int buf_len, 104 int buf_len, int class_flags,
97 CompletionCallback* callback) { 105 CompletionCallback* callback) {
98 callback->Run(WriteFile(file, buf, buf_len)); 106 callback->Run(WriteFile(file, buf, buf_len, class_flags));
99 } 107 }
100 108
101 // FlushFile() is a simple wrapper around fsync() that handles EINTR signals and 109 // FlushFile() is a simple wrapper around fsync() that handles EINTR signals and
102 // calls MapErrorCode() to map errno to net error codes. It tries to flush to 110 // calls MapErrorCode() to map errno to net error codes. It tries to flush to
103 // completion. 111 // completion.
104 int FlushFile(base::PlatformFile file) { 112 int FlushFile(base::PlatformFile file, int class_flags) {
105 base::ThreadRestrictions::AssertIOAllowed(); 113 base::ThreadRestrictions::AssertIOAllowed();
106 ssize_t res = HANDLE_EINTR(fsync(file)); 114 ssize_t res = HANDLE_EINTR(fsync(file));
107 if (res == -1) 115 if (res == -1) {
108 return MapErrorCode(errno); 116 int error = errno;
117 RecordFileError(error, FILE_ERROR_TYPES_FLUSH, class_flags);
118 return MapErrorCode(error);
119 }
109 return res; 120 return res;
110 } 121 }
111 122
112 } // namespace 123 } // namespace
113 124
114 // CancelableCallbackTask takes ownership of the Callback. This task gets 125 // CancelableCallbackTask takes ownership of the Callback. This task gets
115 // posted to the MessageLoopForIO instance. 126 // posted to the MessageLoopForIO instance.
116 class CancelableCallbackTask : public CancelableTask { 127 class CancelableCallbackTask : public CancelableTask {
117 public: 128 public:
118 explicit CancelableCallbackTask(Callback0::Type* callback) 129 explicit CancelableCallbackTask(Callback0::Type* callback)
(...skipping 10 matching lines...) Expand all
129 140
130 private: 141 private:
131 bool canceled_; 142 bool canceled_;
132 scoped_ptr<Callback0::Type> callback_; 143 scoped_ptr<Callback0::Type> callback_;
133 }; 144 };
134 145
135 // FileStream::AsyncContext ---------------------------------------------- 146 // FileStream::AsyncContext ----------------------------------------------
136 147
137 class FileStream::AsyncContext { 148 class FileStream::AsyncContext {
138 public: 149 public:
139 AsyncContext(); 150 explicit AsyncContext();
ahendrickson 2011/08/12 16:06:24 Removed 'explicit'
140 ~AsyncContext(); 151 ~AsyncContext();
141 152
142 // These methods post synchronous read() and write() calls to a WorkerThread. 153 // These methods post synchronous read() and write() calls to a WorkerThread.
143 void InitiateAsyncRead( 154 void InitiateAsyncRead(
144 base::PlatformFile file, char* buf, int buf_len, 155 base::PlatformFile file, char* buf, int buf_len, int class_flags,
145 CompletionCallback* callback); 156 CompletionCallback* callback);
146 void InitiateAsyncWrite( 157 void InitiateAsyncWrite(
147 base::PlatformFile file, const char* buf, int buf_len, 158 base::PlatformFile file, const char* buf, int buf_len, int class_flags,
148 CompletionCallback* callback); 159 CompletionCallback* callback);
149 160
150 CompletionCallback* callback() const { return callback_; } 161 CompletionCallback* callback() const { return callback_; }
151 162
152 // Called by the WorkerPool thread executing the IO after the IO completes. 163 // Called by the WorkerPool thread executing the IO after the IO completes.
153 // This method queues RunAsynchronousCallback() on the MessageLoop and signals 164 // This method queues RunAsynchronousCallback() on the MessageLoop and signals
154 // |background_io_completed_callback_|, in case the destructor is waiting. In 165 // |background_io_completed_callback_|, in case the destructor is waiting. In
155 // that case, the destructor will call RunAsynchronousCallback() instead, and 166 // that case, the destructor will call RunAsynchronousCallback() instead, and
156 // cancel |message_loop_task_|. 167 // cancel |message_loop_task_|.
157 // |result| is the result of the Read/Write task. 168 // |result| is the result of the Read/Write task.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 RunAsynchronousCallback(); 215 RunAsynchronousCallback();
205 if (need_to_wait) { 216 if (need_to_wait) {
206 // We want to see if we block the message loop for too long. 217 // We want to see if we block the message loop for too long.
207 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose", 218 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose",
208 base::TimeTicks::Now() - start); 219 base::TimeTicks::Now() - start);
209 } 220 }
210 } 221 }
211 } 222 }
212 223
213 void FileStream::AsyncContext::InitiateAsyncRead( 224 void FileStream::AsyncContext::InitiateAsyncRead(
214 base::PlatformFile file, char* buf, int buf_len, 225 base::PlatformFile file, char* buf, int buf_len, int class_flags,
215 CompletionCallback* callback) { 226 CompletionCallback* callback) {
216 DCHECK(!callback_); 227 DCHECK(!callback_);
217 callback_ = callback; 228 callback_ = callback;
218 229
219 base::WorkerPool::PostTask(FROM_HERE, 230 base::WorkerPool::PostTask(FROM_HERE,
220 NewRunnableFunction( 231 NewRunnableFunction(
221 &ReadFileTask, 232 &ReadFileTask,
222 file, buf, buf_len, 233 file, buf, buf_len, class_flags,
223 &background_io_completed_callback_), 234 &background_io_completed_callback_),
224 true /* task_is_slow */); 235 true /* task_is_slow */);
225 } 236 }
226 237
227 void FileStream::AsyncContext::InitiateAsyncWrite( 238 void FileStream::AsyncContext::InitiateAsyncWrite(
228 base::PlatformFile file, const char* buf, int buf_len, 239 base::PlatformFile file, const char* buf, int buf_len, int class_flags,
229 CompletionCallback* callback) { 240 CompletionCallback* callback) {
230 DCHECK(!callback_); 241 DCHECK(!callback_);
231 callback_ = callback; 242 callback_ = callback;
232 243
233 base::WorkerPool::PostTask(FROM_HERE, 244 base::WorkerPool::PostTask(FROM_HERE,
234 NewRunnableFunction( 245 NewRunnableFunction(
235 &WriteFileTask, 246 &WriteFileTask,
236 file, buf, buf_len, 247 file, buf, buf_len, class_flags,
237 &background_io_completed_callback_), 248 &background_io_completed_callback_),
238 true /* task_is_slow */); 249 true /* task_is_slow */);
239 } 250 }
240 251
241 void FileStream::AsyncContext::OnBackgroundIOCompleted(int result) { 252 void FileStream::AsyncContext::OnBackgroundIOCompleted(int result) {
242 result_ = result; 253 result_ = result;
243 message_loop_task_ = new CancelableCallbackTask( 254 message_loop_task_ = new CancelableCallbackTask(
244 NewCallback(this, &AsyncContext::RunAsynchronousCallback)); 255 NewCallback(this, &AsyncContext::RunAsynchronousCallback));
245 message_loop_->PostTask(FROM_HERE, message_loop_task_); 256 message_loop_->PostTask(FROM_HERE, message_loop_task_);
246 background_io_completed_.Signal(); 257 background_io_completed_.Signal();
(...skipping 24 matching lines...) Expand all
271 282
272 // FileStream ------------------------------------------------------------ 283 // FileStream ------------------------------------------------------------
273 284
274 FileStream::FileStream() 285 FileStream::FileStream()
275 : file_(base::kInvalidPlatformFileValue), 286 : file_(base::kInvalidPlatformFileValue),
276 open_flags_(0), 287 open_flags_(0),
277 auto_closed_(true) { 288 auto_closed_(true) {
278 DCHECK(!IsOpen()); 289 DCHECK(!IsOpen());
279 } 290 }
280 291
292 FileStream::FileStream(int class_flags)
293 : file_(base::kInvalidPlatformFileValue),
294 open_flags_(0),
295 auto_closed_(true),
296 class_flags_(class_flags) {
297 DCHECK(!IsOpen());
298 }
299
281 FileStream::FileStream(base::PlatformFile file, int flags) 300 FileStream::FileStream(base::PlatformFile file, int flags)
282 : file_(file), 301 : file_(file),
283 open_flags_(flags), 302 open_flags_(flags),
284 auto_closed_(false) { 303 auto_closed_(false) {
285 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to 304 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to
286 // make sure we will perform asynchronous File IO to it. 305 // make sure we will perform asynchronous File IO to it.
287 if (flags & base::PLATFORM_FILE_ASYNC) { 306 if (flags & base::PLATFORM_FILE_ASYNC) {
288 async_context_.reset(new AsyncContext()); 307 async_context_.reset(new AsyncContext());
289 } 308 }
290 } 309 }
291 310
311 FileStream::FileStream(base::PlatformFile file, int flags, int class_flags)
312 : file_(file),
313 open_flags_(flags),
314 auto_closed_(false),
315 class_flags_(class_flags) {
316 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to
317 // make sure we will perform asynchronous File IO to it.
318 if (flags & base::PLATFORM_FILE_ASYNC) {
319 async_context_.reset(new AsyncContext());
320 }
321 }
322
292 FileStream::~FileStream() { 323 FileStream::~FileStream() {
293 if (auto_closed_) 324 if (auto_closed_)
294 Close(); 325 Close();
295 } 326 }
296 327
297 void FileStream::Close() { 328 void FileStream::Close() {
298 // Abort any existing asynchronous operations. 329 // Abort any existing asynchronous operations.
299 async_context_.reset(); 330 async_context_.reset();
300 331
301 if (file_ != base::kInvalidPlatformFileValue) { 332 if (file_ != base::kInvalidPlatformFileValue) {
302 if (close(file_) != 0) { 333 if (close(file_) != 0) {
303 NOTREACHED(); 334 NOTREACHED();
304 } 335 }
305 file_ = base::kInvalidPlatformFileValue; 336 file_ = base::kInvalidPlatformFileValue;
306 } 337 }
307 } 338 }
308 339
309 int FileStream::Open(const FilePath& path, int open_flags) { 340 int FileStream::Open(const FilePath& path, int open_flags) {
310 if (IsOpen()) { 341 if (IsOpen()) {
311 DLOG(FATAL) << "File is already open!"; 342 DLOG(FATAL) << "File is already open!";
312 return ERR_UNEXPECTED; 343 return ERR_UNEXPECTED;
313 } 344 }
314 345
315 open_flags_ = open_flags; 346 open_flags_ = open_flags;
316 file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); 347 file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL);
317 if (file_ == base::kInvalidPlatformFileValue) { 348 if (file_ == base::kInvalidPlatformFileValue) {
349 RecordFileError(errno, FILE_ERROR_TYPES_OPEN, class_flags_);
ahendrickson 2011/08/12 16:06:24 Saved errno, in case it gets changed by the record
318 return MapErrorCode(errno); 350 return MapErrorCode(errno);
319 } 351 }
320 352
321 if (open_flags_ & base::PLATFORM_FILE_ASYNC) { 353 if (open_flags_ & base::PLATFORM_FILE_ASYNC) {
322 async_context_.reset(new AsyncContext()); 354 async_context_.reset(new AsyncContext());
323 } 355 }
324 356
325 return OK; 357 return OK;
326 } 358 }
327 359
328 bool FileStream::IsOpen() const { 360 bool FileStream::IsOpen() const {
329 return file_ != base::kInvalidPlatformFileValue; 361 return file_ != base::kInvalidPlatformFileValue;
330 } 362 }
331 363
332 int64 FileStream::Seek(Whence whence, int64 offset) { 364 int64 FileStream::Seek(Whence whence, int64 offset) {
333 base::ThreadRestrictions::AssertIOAllowed(); 365 base::ThreadRestrictions::AssertIOAllowed();
334 366
335 if (!IsOpen()) 367 if (!IsOpen()) {
368 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
336 return ERR_UNEXPECTED; 369 return ERR_UNEXPECTED;
370 }
337 371
338 // If we're in async, make sure we don't have a request in flight. 372 // If we're in async, make sure we don't have a request in flight.
339 DCHECK(!async_context_.get() || !async_context_->callback()); 373 DCHECK(!async_context_.get() || !async_context_->callback());
340 374
341 off_t res = lseek(file_, static_cast<off_t>(offset), 375 off_t res = lseek(file_, static_cast<off_t>(offset),
342 static_cast<int>(whence)); 376 static_cast<int>(whence));
343 if (res == static_cast<off_t>(-1)) 377 if (res == static_cast<off_t>(-1)) {
378 RecordFileError(errno, FILE_ERROR_TYPES_SEEK, class_flags_);
344 return MapErrorCode(errno); 379 return MapErrorCode(errno);
380 }
345 381
346 return res; 382 return res;
347 } 383 }
348 384
349 int64 FileStream::Available() { 385 int64 FileStream::Available() {
350 base::ThreadRestrictions::AssertIOAllowed(); 386 base::ThreadRestrictions::AssertIOAllowed();
351 387
352 if (!IsOpen()) 388 if (!IsOpen()) {
389 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
353 return ERR_UNEXPECTED; 390 return ERR_UNEXPECTED;
391 }
354 392
355 int64 cur_pos = Seek(FROM_CURRENT, 0); 393 int64 cur_pos = Seek(FROM_CURRENT, 0);
356 if (cur_pos < 0) 394 if (cur_pos < 0)
357 return cur_pos; 395 return cur_pos;
358 396
359 struct stat info; 397 struct stat info;
360 if (fstat(file_, &info) != 0) 398 if (fstat(file_, &info) != 0) {
399 RecordFileError(errno, FILE_ERROR_TYPES_GET_SIZE, class_flags_);
361 return MapErrorCode(errno); 400 return MapErrorCode(errno);
362 401 }
363 int64 size = static_cast<int64>(info.st_size); 402 int64 size = static_cast<int64>(info.st_size);
364 DCHECK_GT(size, cur_pos); 403 DCHECK_GT(size, cur_pos);
365 404
366 return size - cur_pos; 405 return size - cur_pos;
367 } 406 }
368 407
369 int FileStream::Read( 408 int FileStream::Read(
370 char* buf, int buf_len, CompletionCallback* callback) { 409 char* buf, int buf_len, CompletionCallback* callback) {
371 if (!IsOpen()) 410 if (!IsOpen()) {
411 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
372 return ERR_UNEXPECTED; 412 return ERR_UNEXPECTED;
413 }
373 414
374 // read(..., 0) will return 0, which indicates end-of-file. 415 // read(..., 0) will return 0, which indicates end-of-file.
375 DCHECK(buf_len > 0); 416 DCHECK(buf_len > 0);
376 DCHECK(open_flags_ & base::PLATFORM_FILE_READ); 417 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
377 418
378 if (async_context_.get()) { 419 if (async_context_.get()) {
379 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 420 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
380 // If we're in async, make sure we don't have a request in flight. 421 // If we're in async, make sure we don't have a request in flight.
381 DCHECK(!async_context_->callback()); 422 DCHECK(!async_context_->callback());
382 async_context_->InitiateAsyncRead(file_, buf, buf_len, callback); 423 async_context_->InitiateAsyncRead(file_, buf, buf_len, class_flags_,
424 callback);
383 return ERR_IO_PENDING; 425 return ERR_IO_PENDING;
384 } else { 426 } else {
385 return ReadFile(file_, buf, buf_len); 427 return ReadFile(file_, buf, buf_len, class_flags_);
386 } 428 }
387 } 429 }
388 430
389 int FileStream::ReadUntilComplete(char *buf, int buf_len) { 431 int FileStream::ReadUntilComplete(char *buf, int buf_len) {
390 int to_read = buf_len; 432 int to_read = buf_len;
391 int bytes_total = 0; 433 int bytes_total = 0;
392 434
393 do { 435 do {
394 int bytes_read = Read(buf, to_read, NULL); 436 int bytes_read = Read(buf, to_read, NULL);
395 if (bytes_read <= 0) { 437 if (bytes_read <= 0) {
396 if (bytes_total == 0) 438 if (bytes_total == 0)
397 return bytes_read; 439 return bytes_read;
398 440
399 return bytes_total; 441 return bytes_total;
400 } 442 }
401 443
402 bytes_total += bytes_read; 444 bytes_total += bytes_read;
403 buf += bytes_read; 445 buf += bytes_read;
404 to_read -= bytes_read; 446 to_read -= bytes_read;
405 } while (bytes_total < buf_len); 447 } while (bytes_total < buf_len);
406 448
407 return bytes_total; 449 return bytes_total;
408 } 450 }
409 451
410 int FileStream::Write( 452 int FileStream::Write(
411 const char* buf, int buf_len, CompletionCallback* callback) { 453 const char* buf, int buf_len, CompletionCallback* callback) {
412 // write(..., 0) will return 0, which indicates end-of-file. 454 // write(..., 0) will return 0, which indicates end-of-file.
413 DCHECK_GT(buf_len, 0); 455 DCHECK_GT(buf_len, 0);
414 456
415 if (!IsOpen()) 457 if (!IsOpen()) {
458 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
416 return ERR_UNEXPECTED; 459 return ERR_UNEXPECTED;
460 }
417 461
418 if (async_context_.get()) { 462 if (async_context_.get()) {
419 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 463 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
420 // If we're in async, make sure we don't have a request in flight. 464 // If we're in async, make sure we don't have a request in flight.
421 DCHECK(!async_context_->callback()); 465 DCHECK(!async_context_->callback());
422 async_context_->InitiateAsyncWrite(file_, buf, buf_len, callback); 466 async_context_->InitiateAsyncWrite(file_, buf, buf_len, class_flags_,
467 callback);
423 return ERR_IO_PENDING; 468 return ERR_IO_PENDING;
424 } else { 469 } else {
425 return WriteFile(file_, buf, buf_len); 470 return WriteFile(file_, buf, buf_len, class_flags_);
426 } 471 }
427 } 472 }
428 473
429 int64 FileStream::Truncate(int64 bytes) { 474 int64 FileStream::Truncate(int64 bytes) {
430 base::ThreadRestrictions::AssertIOAllowed(); 475 base::ThreadRestrictions::AssertIOAllowed();
431 476
432 if (!IsOpen()) 477 if (!IsOpen()) {
478 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
433 return ERR_UNEXPECTED; 479 return ERR_UNEXPECTED;
480 }
434 481
435 // We better be open for reading. 482 // We better be open for reading.
436 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 483 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
437 484
438 // Seek to the position to truncate from. 485 // Seek to the position to truncate from.
439 int64 seek_position = Seek(FROM_BEGIN, bytes); 486 int64 seek_position = Seek(FROM_BEGIN, bytes);
440 if (seek_position != bytes) 487 if (seek_position != bytes)
441 return ERR_UNEXPECTED; 488 return ERR_UNEXPECTED;
442 489
443 // And truncate the file. 490 // And truncate the file.
444 int result = ftruncate(file_, bytes); 491 int result = ftruncate(file_, bytes);
445 return result == 0 ? seek_position : MapErrorCode(errno); 492 if (result == 0)
493 return seek_position;
494
495 RecordFileError(errno, FILE_ERROR_TYPES_SET_EOF, class_flags_);
496 return MapErrorCode(errno);
446 } 497 }
447 498
448 int FileStream::Flush() { 499 int FileStream::Flush() {
449 if (!IsOpen()) 500 if (!IsOpen()) {
501 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
450 return ERR_UNEXPECTED; 502 return ERR_UNEXPECTED;
503 }
451 504
452 return FlushFile(file_); 505 return FlushFile(file_, class_flags_);
506 }
507
508 void FileStream::EnableRecording(bool enable, int class_flags) {
509 if (enable)
510 class_flags_ |= class_flags;
511 else
512 class_flags_ &= ~class_flags;
453 } 513 }
454 514
455 } // namespace net 515 } // namespace net
OLDNEW
« no previous file with comments | « net/base/file_stream.cc ('k') | net/base/file_stream_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698