diff options
author | ahendrickson@chromium.org <ahendrickson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-02 18:49:43 +0000 |
---|---|---|
committer | ahendrickson@chromium.org <ahendrickson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-02 18:49:43 +0000 |
commit | 1034299e794d0ba846309c43046eb8bb8a740e27 (patch) | |
tree | 9844e4cfd15857aa0d772432f8cd01983bc1df56 | |
parent | e5eed6d9790191c9ce4705167d1bb1166d521699 (diff) | |
download | chromium_src-1034299e794d0ba846309c43046eb8bb8a740e27.zip chromium_src-1034299e794d0ba846309c43046eb8bb8a740e27.tar.gz chromium_src-1034299e794d0ba846309c43046eb8bb8a740e27.tar.bz2 |
Added Net logging to FileStream.
The net logging doesn't currently do anything, but is ready if some system wants to pass it in.
This is the first of 4 CLs that will enable net logging for downloads.
BUG=None
TEST=None
Review URL: https://chromiumcodereview.appspot.com/9288084
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120226 0039d316-1c4b-4281-b951-d872f2087c98
37 files changed, 537 insertions, 138 deletions
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc index c933680..8ab2de4 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -93,7 +93,8 @@ class Writer : public base::RefCountedThreadSafe<Writer> { : bookmarks_(bookmarks), path_(path), favicons_map_(favicons_map), - observer_(observer) { + observer_(observer), + file_stream_(NULL) { } // Writing bookmarks and favicons data to file. diff --git a/chrome/browser/chromeos/imageburner/burn_manager.cc b/chrome/browser/chromeos/imageburner/burn_manager.cc index 7154c16..3b8db3f 100644 --- a/chrome/browser/chromeos/imageburner/burn_manager.cc +++ b/chrome/browser/chromeos/imageburner/burn_manager.cc @@ -57,7 +57,7 @@ void ReadFile(const FilePath& path, void CreateFileStream( const FilePath& file_path, base::Callback<void(net::FileStream* file_stream)> callback) { - scoped_ptr<net::FileStream> file_stream(new net::FileStream); + scoped_ptr<net::FileStream> file_stream(new net::FileStream(NULL)); // TODO(tbarzic): Save temp image file to temp folder instead of Downloads // once extracting image directly to removalbe device is implemented if (file_stream->Open(file_path, base::PLATFORM_FILE_OPEN_ALWAYS | diff --git a/chrome/browser/net/passive_log_collector.cc b/chrome/browser/net/passive_log_collector.cc index 9ca4b63..5006bdb 100644 --- a/chrome/browser/net/passive_log_collector.cc +++ b/chrome/browser/net/passive_log_collector.cc @@ -87,6 +87,8 @@ PassiveLogCollector::PassiveLogCollector() &cert_verifier_job_tracker_; trackers_[net::NetLog::SOURCE_HTTP_PIPELINED_CONNECTION] = &http_pipelined_connection_tracker_; + trackers_[net::NetLog::SOURCE_FILESTREAM] = + &file_stream_tracker_; // Make sure our mapping is up-to-date. for (size_t i = 0; i < arraysize(trackers_); ++i) DCHECK(trackers_[i]) << "Unhandled SourceType: " << i; @@ -844,3 +846,30 @@ PassiveLogCollector::HttpPipelinedConnectionTracker::DoAddEntry( } return ACTION_NONE; } + +//---------------------------------------------------------------------------- +// FileStreamTracker +//---------------------------------------------------------------------------- + +const size_t +PassiveLogCollector::FileStreamTracker::kMaxNumSources = 100; + +const size_t +PassiveLogCollector::FileStreamTracker::kMaxGraveyardSize = 25; + +PassiveLogCollector:: + FileStreamTracker::FileStreamTracker() + : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { +} + +PassiveLogCollector::SourceTracker::Action +PassiveLogCollector::FileStreamTracker::DoAddEntry( + const ChromeNetLog::Entry& entry, + SourceInfo* out_info) { + AddEntryToSourceInfo(entry, out_info); + if (entry.type == net::NetLog::TYPE_FILE_STREAM_ALIVE && + entry.phase == net::NetLog::PHASE_END) { + return ACTION_MOVE_TO_GRAVEYARD; + } + return ACTION_NONE; +} diff --git a/chrome/browser/net/passive_log_collector.h b/chrome/browser/net/passive_log_collector.h index 2cb9ab4..c3b8da5 100644 --- a/chrome/browser/net/passive_log_collector.h +++ b/chrome/browser/net/passive_log_collector.h @@ -446,6 +446,21 @@ class PassiveLogCollector : public ChromeNetLog::ThreadSafeObserverImpl { DISALLOW_COPY_AND_ASSIGN(HttpPipelinedConnectionTracker); }; + // Tracks the log entries for the last seen SOURCE_FILESTREAM. + class FileStreamTracker : public SourceTracker { + public: + static const size_t kMaxNumSources; + static const size_t kMaxGraveyardSize; + + FileStreamTracker(); + + private: + virtual Action DoAddEntry(const ChromeNetLog::Entry& entry, + SourceInfo* out_info) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(FileStreamTracker); + }; + PassiveLogCollector(); virtual ~PassiveLogCollector(); @@ -492,6 +507,7 @@ class PassiveLogCollector : public ChromeNetLog::ThreadSafeObserverImpl { UDPSocketTracker udp_socket_tracker_; CertVerifierJobTracker cert_verifier_job_tracker_; HttpPipelinedConnectionTracker http_pipelined_connection_tracker_; + FileStreamTracker file_stream_tracker_; // This array maps each NetLog::SourceType to one of the tracker instances // defined above. Use of this array avoid duplicating the list of trackers diff --git a/chrome/browser/resources/net_internals/events_view.css b/chrome/browser/resources/net_internals/events_view.css index 3b0c7bb..58c32ea 100644 --- a/chrome/browser/resources/net_internals/events_view.css +++ b/chrome/browser/resources/net_internals/events_view.css @@ -97,6 +97,10 @@ color: green; } +#events-view-source-list-tbody .source_FILESTREAM { + color: #700070; +} + #events-view-source-list-tbody .source_NONE { color: red; } diff --git a/chrome/browser/resources/net_internals/source_entry.js b/chrome/browser/resources/net_internals/source_entry.js index 389369b..c24f27b 100644 --- a/chrome/browser/resources/net_internals/source_entry.js +++ b/chrome/browser/resources/net_internals/source_entry.js @@ -132,6 +132,9 @@ var SourceEntry = (function() { case LogSourceType.DNS_TRANSACTION: this.description_ = e.params.hostname; break; + case LogSourceType.FILESTREAM: + this.description_ = e.params.file_name; + break; } if (this.description_ == undefined) @@ -156,6 +159,11 @@ var SourceEntry = (function() { getStartEntry_: function() { if (this.entries_.length < 1) return undefined; + if (this.entries_[0].source.type == LogSourceType.FILESTREAM) { + var e = this.findLogEntryByType_(LogEventType.FILE_STREAM_OPEN); + if (e != undefined) + return e; + } if (this.entries_.length >= 2) { if (this.entries_[0].type == LogEventType.REQUEST_ALIVE || this.entries_[0].type == LogEventType.SOCKET_POOL_CONNECT_JOB || @@ -166,6 +174,19 @@ var SourceEntry = (function() { return this.entries_[0]; }, + /** + * Returns the first entry with the specified type, or undefined if not + * found. + */ + findLogEntryByType_: function(type) { + for (var i = 0; i < this.entries_.length; ++i) { + if (this.entries_[i].type == type) { + return this.entries_[i]; + } + } + return undefined; + }, + getLogEntries: function() { return this.entries_; }, diff --git a/chrome/browser/safe_browsing/bloom_filter.cc b/chrome/browser/safe_browsing/bloom_filter.cc index b734009..c21c1c0 100644 --- a/chrome/browser/safe_browsing/bloom_filter.cc +++ b/chrome/browser/safe_browsing/bloom_filter.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -88,7 +88,7 @@ bool BloomFilter::Exists(SBPrefix hash) const { // static. BloomFilter* BloomFilter::LoadFile(const FilePath& filter_name) { - net::FileStream filter; + net::FileStream filter(NULL); if (filter.Open(filter_name, base::PLATFORM_FILE_OPEN | @@ -154,7 +154,7 @@ BloomFilter* BloomFilter::LoadFile(const FilePath& filter_name) { } bool BloomFilter::WriteFile(const FilePath& filter_name) const { - net::FileStream filter; + net::FileStream filter(NULL); if (filter.Open(filter_name, base::PLATFORM_FILE_WRITE | diff --git a/chrome/browser/sessions/session_backend.cc b/chrome/browser/sessions/session_backend.cc index 916f04a..f9d2b8c 100644 --- a/chrome/browser/sessions/session_backend.cc +++ b/chrome/browser/sessions/session_backend.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -45,7 +45,7 @@ class SessionFileReader { buffer_(SessionBackend::kFileReadBufferSize, 0), buffer_position_(0), available_count_(0) { - file_.reset(new net::FileStream()); + file_.reset(new net::FileStream(NULL)); if (file_util::PathExists(path)) file_->Open(path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); } @@ -363,7 +363,7 @@ void SessionBackend::ResetFile() { net::FileStream* SessionBackend::OpenAndWriteHeader(const FilePath& path) { DCHECK(!path.empty()); - scoped_ptr<net::FileStream> file(new net::FileStream()); + scoped_ptr<net::FileStream> file(new net::FileStream(NULL)); if (file->Open(path, base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_READ) != net::OK) diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index c35bee5..28c5db2 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -286,7 +286,7 @@ const int kPreloadIDs[] = { // Returns a piece of memory with the contents of the file |path|. RefCountedMemory* ReadFileData(const FilePath& path) { if (!path.empty()) { - net::FileStream file; + net::FileStream file(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; if (file.Open(path, flags) == net::OK) { int64 avail = file.Available(); diff --git a/chrome/common/zip.cc b/chrome/common/zip.cc index c6dc6fa..a5635c0 100644 --- a/chrome/common/zip.cc +++ b/chrome/common/zip.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,7 +18,7 @@ namespace { bool AddFileToZip(zipFile zip_file, const FilePath& src_dir) { - net::FileStream stream; + net::FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; if (stream.Open(src_dir, flags) != 0) { DLOG(ERROR) << "Could not open stream for path " diff --git a/chrome/common/zip_reader.cc b/chrome/common/zip_reader.cc index 461a65a..60fba5e 100644 --- a/chrome/common/zip_reader.cc +++ b/chrome/common/zip_reader.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -190,7 +190,7 @@ bool ZipReader::ExtractCurrentEntryToFilePath( if (!file_util::CreateDirectory(output_dir_path)) return false; - net::FileStream stream; + net::FileStream stream(NULL); const int flags = (base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE); if (stream.Open(output_file_path, flags) != 0) diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc index b346ef2..a9da47f 100644 --- a/content/browser/download/base_file.cc +++ b/content/browser/download/base_file.cc @@ -449,7 +449,7 @@ void BaseFile::AnnotateWithSourceInformation() { } void BaseFile::CreateFileStream() { - file_stream_.reset(new net::FileStream); + file_stream_.reset(new net::FileStream(NULL)); } net::Error BaseFile::Open() { diff --git a/content/browser/download/base_file_unittest.cc b/content/browser/download/base_file_unittest.cc index 911af194..646ef00 100644 --- a/content/browser/download/base_file_unittest.cc +++ b/content/browser/download/base_file_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -108,7 +108,7 @@ class BaseFileTest : public testing::Test { return false; // Create a new file stream. - mock_file_stream_.reset(new net::testing::MockFileStream); + mock_file_stream_.reset(new net::testing::MockFileStream(NULL)); if (mock_file_stream_->Open( path, base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE) != 0) { diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index ae1ada7..6a15281 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc @@ -1010,7 +1010,7 @@ TEST_F(DownloadManagerTest, MAYBE_DownloadFileErrorTest) { ASSERT_TRUE(file_util::CreateTemporaryFile(&path)); // This file stream will be used, until the first rename occurs. - net::FileStream* stream = new net::FileStream; + net::FileStream* stream = new net::FileStream(NULL); ASSERT_EQ(0, stream->Open( path, base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE)); diff --git a/content/browser/download/drag_download_util.cc b/content/browser/download/drag_download_util.cc index a0d6f8a..ed781bb 100644 --- a/content/browser/download/drag_download_util.cc +++ b/content/browser/download/drag_download_util.cc @@ -59,7 +59,7 @@ bool ParseDownloadMetadata(const string16& metadata, FileStream* CreateFileStreamForDrop(FilePath* file_path) { DCHECK(file_path && !file_path->empty()); - scoped_ptr<FileStream> file_stream(new FileStream); + scoped_ptr<FileStream> file_stream(new FileStream(NULL)); const int kMaxSeq = 99; for (int seq = 0; seq <= kMaxSeq; seq++) { FilePath new_file_path; diff --git a/content/browser/renderer_host/redirect_to_file_resource_handler.cc b/content/browser/renderer_host/redirect_to_file_resource_handler.cc index 54329db..e4147f0 100644 --- a/content/browser/renderer_host/redirect_to_file_resource_handler.cc +++ b/content/browser/renderer_host/redirect_to_file_resource_handler.cc @@ -164,7 +164,8 @@ void RedirectToFileResourceHandler::DidCreateTemporaryFile( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(), base::PLATFORM_FILE_WRITE | - base::PLATFORM_FILE_ASYNC)); + base::PLATFORM_FILE_ASYNC, + NULL)); host_->RegisterDownloadedTempFile( process_id_, request_id_, deletable_file_.get()); host_->StartDeferredRequest(process_id_, request_id_); diff --git a/net/base/file_stream.h b/net/base/file_stream.h index f2a8f7f..a50d9c0 100644 --- a/net/base/file_stream.h +++ b/net/base/file_stream.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,6 +15,7 @@ #include "base/platform_file.h" #include "net/base/completion_callback.h" #include "net/base/net_export.h" +#include "net/base/net_log.h" class FilePath; @@ -30,15 +31,19 @@ enum Whence { class NET_EXPORT FileStream { public: - FileStream(); + // Creates a |FileStream| with a new |BoundNetLog| (based on |net_log|) + // attached. |net_log| may be NULL if no logging is needed. + explicit FileStream(net::NetLog* net_log); // Construct a FileStream with an existing file handle and opening flags. // |file| is valid file handle. // |flags| is a bitfield of base::PlatformFileFlags when the file handle was // opened. + // |net_log| is the net log pointer to use to create a |BoundNetLog|. May be + // NULL if logging is not needed. // The already opened file will not be automatically closed when FileStream // is destructed. - FileStream(base::PlatformFile file, int flags); + FileStream(base::PlatformFile file, int flags, net::NetLog* net_log); virtual ~FileStream(); @@ -136,6 +141,13 @@ class NET_EXPORT FileStream { // Turns on UMA error statistics gathering. void EnableErrorStatistics(); + // Sets the source reference for net-internals logging. + // Creates source dependency events between |owner_bound_net_log| and + // |bound_net_log_|. Each gets an event showing the dependency on the other. + // If only one of those is valid, it gets an event showing that a change + // of ownership happened, but without details. + void SetBoundNetLogSource(const net::BoundNetLog& owner_bound_net_log); + private: class AsyncContext; friend class AsyncContext; @@ -149,6 +161,7 @@ class NET_EXPORT FileStream { int open_flags_; bool auto_closed_; bool record_uma_; + net::BoundNetLog bound_net_log_; DISALLOW_COPY_AND_ASSIGN(FileStream); }; diff --git a/net/base/file_stream_metrics.cc b/net/base/file_stream_metrics.cc index 7ffa96d..4dc0576 100644 --- a/net/base/file_stream_metrics.cc +++ b/net/base/file_stream_metrics.cc @@ -1,9 +1,10 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/base/file_stream_metrics.h" +#include "base/basictypes.h" #include "base/logging.h" #include "base/metrics/histogram.h" @@ -11,6 +12,20 @@ namespace net { namespace { +const char* FileErrorSourceStrings[] = { + "OPEN", + "WRITE", + "READ", + "SEEK", + "FLUSH", + "SET_EOF", + "GET_SIZE" +}; + +COMPILE_ASSERT(ARRAYSIZE_UNSAFE(FileErrorSourceStrings) == + FILE_ERROR_SOURCE_COUNT, + file_error_source_enum_has_changed); + void RecordFileErrorTypeCount(FileErrorSource source) { UMA_HISTOGRAM_ENUMERATION( "Net.FileErrorType_Counts", source, FILE_ERROR_SOURCE_COUNT); @@ -78,4 +93,9 @@ void RecordFileError(int error, FileErrorSource source, bool record) { } } +const char* GetFileErrorSourceName(FileErrorSource source) { + DCHECK_NE(FILE_ERROR_SOURCE_COUNT, source); + return FileErrorSourceStrings[source]; +} + } // namespace net diff --git a/net/base/file_stream_metrics.h b/net/base/file_stream_metrics.h index cdf16e5..5adb7e2 100644 --- a/net/base/file_stream_metrics.h +++ b/net/base/file_stream_metrics.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -36,6 +36,9 @@ int MaxFileErrorUmaValue(); // |record| is a flag indicating that we are interested in this error. void RecordFileError(int error, FileErrorSource source, bool record); +// Gets a description for the source of a file error. +const char* GetFileErrorSourceName(FileErrorSource source); + } // namespace net #endif // NET_BASE_FILE_STREAM_METRICS_H_ diff --git a/net/base/file_stream_net_log_parameters.cc b/net/base/file_stream_net_log_parameters.cc new file mode 100644 index 0000000..3a8c42f --- /dev/null +++ b/net/base/file_stream_net_log_parameters.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/file_stream_net_log_parameters.h" + +#include "base/values.h" + +namespace net { + +FileStreamErrorParameters::FileStreamErrorParameters( + const std::string& operation, int os_error, net::Error net_error) + : operation_(operation), os_error_(os_error), net_error_(net_error) { +} + +Value* FileStreamErrorParameters::ToValue() const { + DictionaryValue* dict = new DictionaryValue(); + + dict->SetString("operation", operation_); + dict->SetInteger("os_error", os_error_); + dict->SetInteger("net_error", net_error_); + + return dict; +} + +} // namespace net diff --git a/net/base/file_stream_net_log_parameters.h b/net/base/file_stream_net_log_parameters.h new file mode 100644 index 0000000..92689ab --- /dev/null +++ b/net/base/file_stream_net_log_parameters.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// File stream error reporting. + +#ifndef NET_BASE_FILE_STREAM_NET_LOG_PARAMETERS_H_ +#define NET_BASE_FILE_STREAM_NET_LOG_PARAMETERS_H_ +#pragma once + +#include <string> + +#include "net/base/net_errors.h" +#include "net/base/net_log.h" + +namespace net { + +// NetLog parameters when a FileStream has an error. +class FileStreamErrorParameters : public net::NetLog::EventParameters { + public: + FileStreamErrorParameters(const std::string& operation, + int os_error, + net::Error net_error); + virtual base::Value* ToValue() const OVERRIDE; + + private: + std::string operation_; + int os_error_; + net::Error net_error_; + + DISALLOW_COPY_AND_ASSIGN(FileStreamErrorParameters); +}; + +} // namespace net + +#endif // NET_BASE_FILE_STREAM_NET_LOG_PARAMETERS_H_ diff --git a/net/base/file_stream_posix.cc b/net/base/file_stream_posix.cc index 50b1593..8220a9f 100644 --- a/net/base/file_stream_posix.cc +++ b/net/base/file_stream_posix.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,6 +27,7 @@ #include "base/threading/worker_pool.h" #include "base/synchronization/waitable_event.h" #include "net/base/file_stream_metrics.h" +#include "net/base/file_stream_net_log_parameters.h" #include "net/base/net_errors.h" #if defined(OS_ANDROID) @@ -49,21 +50,38 @@ COMPILE_ASSERT(FROM_BEGIN == SEEK_SET && namespace { -int RecordAndMapError(int error, FileErrorSource source, bool record_uma) { +int RecordAndMapError(int error, + FileErrorSource source, + bool record_uma, + const net::BoundNetLog& bound_net_log) { + net::Error net_error = MapSystemError(error); + + bound_net_log.AddEvent( + net::NetLog::TYPE_FILE_STREAM_ERROR, + make_scoped_refptr( + new FileStreamErrorParameters(GetFileErrorSourceName(source), + error, + net_error))); + RecordFileError(error, source, record_uma); - return MapSystemError(error); + + return net_error; } // ReadFile() is a simple wrapper around read() that handles EINTR signals and // calls MapSystemError() to map errno to net error codes. -int ReadFile(base::PlatformFile file, char* buf, int buf_len, bool record_uma) { +int ReadFile(base::PlatformFile file, + char* buf, + int buf_len, + bool record_uma, + const net::BoundNetLog& bound_net_log) { base::ThreadRestrictions::AssertIOAllowed(); // read(..., 0) returns 0 to indicate end-of-file. // Loop in the case of getting interrupted by a signal. ssize_t res = HANDLE_EINTR(read(file, buf, static_cast<size_t>(buf_len))); if (res == static_cast<ssize_t>(-1)) - RecordAndMapError(errno, FILE_ERROR_SOURCE_READ, record_uma); + RecordAndMapError(errno, FILE_ERROR_SOURCE_READ, record_uma, bound_net_log); return static_cast<int>(res); } @@ -71,37 +89,49 @@ void ReadFileTask(base::PlatformFile file, char* buf, int buf_len, bool record_uma, + const net::BoundNetLog& bound_net_log, const CompletionCallback& callback) { - callback.Run(ReadFile(file, buf, buf_len, record_uma)); + callback.Run(ReadFile(file, buf, buf_len, record_uma, bound_net_log)); } // WriteFile() is a simple wrapper around write() that handles EINTR signals and // calls MapSystemError() to map errno to net error codes. It tries to write to // completion. -int WriteFile(base::PlatformFile file, const char* buf, int buf_len, - bool record_uma) { +int WriteFile(base::PlatformFile file, + const char* buf, + int buf_len, + bool record_uma, + const net::BoundNetLog& bound_net_log) { base::ThreadRestrictions::AssertIOAllowed(); ssize_t res = HANDLE_EINTR(write(file, buf, buf_len)); - if (res == -1) - RecordAndMapError(errno, FILE_ERROR_SOURCE_WRITE, record_uma); + if (res == -1) { + RecordAndMapError(errno, FILE_ERROR_SOURCE_WRITE, record_uma, + bound_net_log); + } return res; } void WriteFileTask(base::PlatformFile file, const char* buf, - int buf_len, bool record_uma, + int buf_len, + bool record_uma, + const net::BoundNetLog& bound_net_log, const CompletionCallback& callback) { - callback.Run(WriteFile(file, buf, buf_len, record_uma)); + callback.Run(WriteFile(file, buf, buf_len, record_uma, bound_net_log)); } // FlushFile() is a simple wrapper around fsync() that handles EINTR signals and // calls MapSystemError() to map errno to net error codes. It tries to flush to // completion. -int FlushFile(base::PlatformFile file, bool record_uma) { +int FlushFile(base::PlatformFile file, + bool record_uma, + const net::BoundNetLog& bound_net_log) { base::ThreadRestrictions::AssertIOAllowed(); ssize_t res = HANDLE_EINTR(fsync(file)); - if (res == -1) - RecordAndMapError(errno, FILE_ERROR_SOURCE_FLUSH, record_uma); + if (res == -1) { + RecordAndMapError(errno, FILE_ERROR_SOURCE_FLUSH, record_uma, + bound_net_log); + } return res; } @@ -138,9 +168,11 @@ class FileStream::AsyncContext { // These methods post synchronous read() and write() calls to a WorkerThread. void InitiateAsyncRead( base::PlatformFile file, char* buf, int buf_len, + const net::BoundNetLog& bound_net_log, const CompletionCallback& callback); void InitiateAsyncWrite( base::PlatformFile file, const char* buf, int buf_len, + const net::BoundNetLog& bound_net_log, const CompletionCallback& callback); const CompletionCallback& callback() const { return callback_; } @@ -207,14 +239,19 @@ FileStream::AsyncContext::~AsyncContext() { void FileStream::AsyncContext::InitiateAsyncRead( base::PlatformFile file, char* buf, int buf_len, + const net::BoundNetLog& bound_net_log, const CompletionCallback& callback) { DCHECK(callback_.is_null()); callback_ = callback; base::WorkerPool::PostTask( FROM_HERE, - base::Bind(&ReadFileTask, file, buf, buf_len, + base::Bind(&ReadFileTask, + file, + buf, + buf_len, record_uma_, + bound_net_log, base::Bind(&AsyncContext::OnBackgroundIOCompleted, base::Unretained(this))), true /* task_is_slow */); @@ -222,18 +259,21 @@ void FileStream::AsyncContext::InitiateAsyncRead( void FileStream::AsyncContext::InitiateAsyncWrite( base::PlatformFile file, const char* buf, int buf_len, + const net::BoundNetLog& bound_net_log, const CompletionCallback& callback) { DCHECK(callback_.is_null()); callback_ = callback; base::WorkerPool::PostTask( FROM_HERE, - base::Bind( - &WriteFileTask, - file, buf, buf_len, - record_uma_, - base::Bind(&AsyncContext::OnBackgroundIOCompleted, - base::Unretained(this))), + base::Bind(&WriteFileTask, + file, + buf, + buf_len, + record_uma_, + bound_net_log, + base::Bind(&AsyncContext::OnBackgroundIOCompleted, + base::Unretained(this))), true /* task_is_slow */); } @@ -273,19 +313,25 @@ void FileStream::AsyncContext::RunAsynchronousCallback() { // FileStream ------------------------------------------------------------ -FileStream::FileStream() +FileStream::FileStream(net::NetLog* net_log) : file_(base::kInvalidPlatformFileValue), open_flags_(0), auto_closed_(true), - record_uma_(false) { - DCHECK(!IsOpen()); + record_uma_(false), + bound_net_log_(net::BoundNetLog::Make(net_log, + net::NetLog::SOURCE_FILESTREAM)) { + bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL); } -FileStream::FileStream(base::PlatformFile file, int flags) +FileStream::FileStream(base::PlatformFile file, int flags, net::NetLog* net_log) : file_(file), open_flags_(flags), auto_closed_(false), - record_uma_(false) { + record_uma_(false), + bound_net_log_(net::BoundNetLog::Make(net_log, + net::NetLog::SOURCE_FILESTREAM)) { + bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL); + // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to // make sure we will perform asynchronous File IO to it. if (flags & base::PLATFORM_FILE_ASYNC) { @@ -296,9 +342,13 @@ FileStream::FileStream(base::PlatformFile file, int flags) FileStream::~FileStream() { if (auto_closed_) Close(); + + bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL);
} void FileStream::Close() { + bound_net_log_.AddEvent(net::NetLog::TYPE_FILE_STREAM_CLOSE, NULL);
+ // Abort any existing asynchronous operations. async_context_.reset(); @@ -307,19 +357,33 @@ void FileStream::Close() { NOTREACHED(); } file_ = base::kInvalidPlatformFileValue; + + bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_OPEN, NULL); } } -int FileStream::Open(const FilePath& path, int open_flags) { +int FileStream::Open(const FilePath& path, int open_flags) {
if (IsOpen()) { DLOG(FATAL) << "File is already open!"; return ERR_UNEXPECTED; } + bound_net_log_.BeginEvent( + net::NetLog::TYPE_FILE_STREAM_OPEN, + make_scoped_refptr( + new net::NetLogStringParameter("file_name", + path.AsUTF8Unsafe()))); + open_flags_ = open_flags; file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); - if (file_ == base::kInvalidPlatformFileValue) - return RecordAndMapError(errno, FILE_ERROR_SOURCE_OPEN, record_uma_); + if (file_ == base::kInvalidPlatformFileValue) { + int net_error = RecordAndMapError(errno, + FILE_ERROR_SOURCE_OPEN, + record_uma_, + bound_net_log_); + bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_OPEN, NULL); + return net_error; + } if (open_flags_ & base::PLATFORM_FILE_ASYNC) async_context_.reset(new AsyncContext()); @@ -342,8 +406,12 @@ int64 FileStream::Seek(Whence whence, int64 offset) { off_t res = lseek(file_, static_cast<off_t>(offset), static_cast<int>(whence)); - if (res == static_cast<off_t>(-1)) - return RecordAndMapError(errno, FILE_ERROR_SOURCE_SEEK, record_uma_); + if (res == static_cast<off_t>(-1)) { + return RecordAndMapError(errno, + FILE_ERROR_SOURCE_SEEK, + record_uma_, + bound_net_log_); + } return res; } @@ -359,8 +427,12 @@ int64 FileStream::Available() { return cur_pos; struct stat info; - if (fstat(file_, &info) != 0) - return RecordAndMapError(errno, FILE_ERROR_SOURCE_GET_SIZE, record_uma_); + if (fstat(file_, &info) != 0) { + return RecordAndMapError(errno, + FILE_ERROR_SOURCE_GET_SIZE, + record_uma_, + bound_net_log_); + } int64 size = static_cast<int64>(info.st_size); DCHECK_GT(size, cur_pos); @@ -383,10 +455,11 @@ int FileStream::Read( DCHECK(async_context_->callback().is_null()); if (record_uma_) async_context_->EnableErrorStatistics(); - async_context_->InitiateAsyncRead(file_, buf, buf_len, callback); + async_context_->InitiateAsyncRead(file_, buf, buf_len, bound_net_log_, + callback); return ERR_IO_PENDING; } else { - return ReadFile(file_, buf, buf_len, record_uma_); + return ReadFile(file_, buf, buf_len, record_uma_, bound_net_log_); } } @@ -425,10 +498,11 @@ int FileStream::Write( DCHECK(async_context_->callback().is_null()); if (record_uma_) async_context_->EnableErrorStatistics(); - async_context_->InitiateAsyncWrite(file_, buf, buf_len, callback); + async_context_->InitiateAsyncWrite(file_, buf, buf_len, bound_net_log_, + callback); return ERR_IO_PENDING; } else { - return WriteFile(file_, buf, buf_len, record_uma_); + return WriteFile(file_, buf, buf_len, record_uma_, bound_net_log_); } } @@ -438,7 +512,7 @@ int64 FileStream::Truncate(int64 bytes) { if (!IsOpen()) return ERR_UNEXPECTED; - // We better be open for reading. + // We'd better be open for writing. DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); // Seek to the position to truncate from. @@ -451,18 +525,45 @@ int64 FileStream::Truncate(int64 bytes) { if (result == 0) return seek_position; - return RecordAndMapError(errno, FILE_ERROR_SOURCE_SET_EOF, record_uma_); + return RecordAndMapError(errno, + FILE_ERROR_SOURCE_SET_EOF, + record_uma_, + bound_net_log_); } int FileStream::Flush() { if (!IsOpen()) return ERR_UNEXPECTED; - return FlushFile(file_, record_uma_); + return FlushFile(file_, record_uma_, bound_net_log_); } void FileStream::EnableErrorStatistics() { record_uma_ = true; } +void FileStream::SetBoundNetLogSource( + const net::BoundNetLog& owner_bound_net_log) { + if ((owner_bound_net_log.source().id == net::NetLog::Source::kInvalidId) && + (bound_net_log_.source().id == net::NetLog::Source::kInvalidId)) { + // Both |BoundNetLog|s are invalid. + return; + } + + // Should never connect to itself. + DCHECK_NE(bound_net_log_.source().id, owner_bound_net_log.source().id); + + bound_net_log_.AddEvent( + net::NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER, + make_scoped_refptr( + new net::NetLogSourceParameter("source_dependency", + owner_bound_net_log.source()))); + + owner_bound_net_log.AddEvent( + net::NetLog::TYPE_FILE_STREAM_SOURCE, + make_scoped_refptr( + new net::NetLogSourceParameter("source_dependency", + bound_net_log_.source()))); +} + } // namespace net diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc index 966a829..c92ce9f 100644 --- a/net/base/file_stream_unittest.cc +++ b/net/base/file_stream_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -53,7 +53,7 @@ namespace { TEST_F(FileStreamTest, BasicOpenClose) { base::PlatformFile file = base::kInvalidPlatformFileValue; { - FileStream stream; + FileStream stream(NULL); int rv = stream.Open(temp_file_path(), base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); EXPECT_EQ(OK, rv); @@ -76,7 +76,7 @@ TEST_F(FileStreamTest, FileHandleLeftOpen) { { // Seek to the beginning of the file and read. - FileStream read_stream(file, flags); + FileStream read_stream(file, flags, NULL); EXPECT_TRUE(read_stream.IsOpen()); } @@ -100,7 +100,7 @@ TEST_F(FileStreamTest, UseFileHandle) { temp_file_path(), flags, &created, NULL); // Seek to the beginning of the file and read. - FileStream read_stream(file, flags); + FileStream read_stream(file, flags, NULL); ASSERT_EQ(0, read_stream.Seek(FROM_BEGIN, 0)); ASSERT_EQ(kTestDataSize, read_stream.Available()); // Read into buffer and compare. @@ -115,7 +115,7 @@ TEST_F(FileStreamTest, UseFileHandle) { flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE; file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL); - FileStream write_stream(file, flags); + FileStream write_stream(file, flags, NULL); ASSERT_EQ(0, write_stream.Seek(FROM_BEGIN, 0)); ASSERT_EQ(kTestDataSize, write_stream.Write(kTestData, kTestDataSize, CompletionCallback())); @@ -128,7 +128,7 @@ TEST_F(FileStreamTest, UseFileHandle) { } TEST_F(FileStreamTest, UseClosedStream) { - FileStream stream; + FileStream stream(NULL); EXPECT_FALSE(stream.IsOpen()); @@ -151,7 +151,7 @@ TEST_F(FileStreamTest, BasicRead) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; int rv = stream.Open(temp_file_path(), flags); @@ -181,7 +181,7 @@ TEST_F(FileStreamTest, AsyncRead) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC; @@ -216,7 +216,7 @@ TEST_F(FileStreamTest, AsyncRead_EarlyClose) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC; @@ -246,7 +246,7 @@ TEST_F(FileStreamTest, BasicRead_FromOffset) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; int rv = stream.Open(temp_file_path(), flags); @@ -281,7 +281,7 @@ TEST_F(FileStreamTest, AsyncRead_FromOffset) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC; @@ -316,7 +316,7 @@ TEST_F(FileStreamTest, AsyncRead_FromOffset) { } TEST_F(FileStreamTest, SeekAround) { - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; int rv = stream.Open(temp_file_path(), flags); @@ -339,7 +339,7 @@ TEST_F(FileStreamTest, SeekAround) { } TEST_F(FileStreamTest, BasicWrite) { - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE; int rv = stream.Open(temp_file_path(), flags); @@ -360,7 +360,7 @@ TEST_F(FileStreamTest, BasicWrite) { } TEST_F(FileStreamTest, AsyncWrite) { - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC; @@ -392,7 +392,7 @@ TEST_F(FileStreamTest, AsyncWrite) { } TEST_F(FileStreamTest, AsyncWrite_EarlyClose) { - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC; @@ -424,7 +424,7 @@ TEST_F(FileStreamTest, AsyncWrite_EarlyClose) { } TEST_F(FileStreamTest, BasicWrite_FromOffset) { - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE; int rv = stream.Open(temp_file_path(), flags); @@ -453,7 +453,7 @@ TEST_F(FileStreamTest, AsyncWrite_FromOffset) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC; @@ -488,7 +488,7 @@ TEST_F(FileStreamTest, BasicReadWrite) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE; @@ -527,7 +527,7 @@ TEST_F(FileStreamTest, BasicWriteRead) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE; @@ -575,7 +575,7 @@ TEST_F(FileStreamTest, BasicAsyncReadWrite) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | @@ -630,7 +630,7 @@ TEST_F(FileStreamTest, BasicAsyncWriteRead) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | @@ -785,7 +785,7 @@ TEST_F(FileStreamTest, AsyncWriteRead) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | @@ -891,7 +891,7 @@ TEST_F(FileStreamTest, AsyncWriteClose) { bool ok = file_util::GetFileSize(temp_file_path(), &file_size); EXPECT_TRUE(ok); - FileStream stream; + FileStream stream(NULL); int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | @@ -923,7 +923,7 @@ TEST_F(FileStreamTest, AsyncWriteClose) { TEST_F(FileStreamTest, Truncate) { int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE; - FileStream write_stream; + FileStream write_stream(NULL); ASSERT_EQ(OK, write_stream.Open(temp_file_path(), flags)); // Write some data to the file. diff --git a/net/base/file_stream_win.cc b/net/base/file_stream_win.cc index 07d365f..1f7ecbf 100644 --- a/net/base/file_stream_win.cc +++ b/net/base/file_stream_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +12,7 @@ #include "base/metrics/histogram.h" #include "base/threading/thread_restrictions.h" #include "net/base/file_stream_metrics.h" +#include "net/base/file_stream_net_log_parameters.h" #include "net/base/net_errors.h" namespace net { @@ -36,9 +37,22 @@ static void IncrementOffset(OVERLAPPED* overlapped, DWORD count) { namespace { -int RecordAndMapError(int error, FileErrorSource source, bool record_uma) { +int RecordAndMapError(int error, + FileErrorSource source, + bool record_uma, + const net::BoundNetLog& bound_net_log) { + net::Error net_error = MapSystemError(error); + + bound_net_log.AddEvent( + net::NetLog::TYPE_FILE_STREAM_ERROR, + make_scoped_refptr( + new FileStreamErrorParameters(GetFileErrorSourceName(source), + error, + net_error))); + RecordFileError(error, source, record_uma); - return MapSystemError(error); + + return net_error; } } // namespace @@ -47,9 +61,10 @@ int RecordAndMapError(int error, FileErrorSource source, bool record_uma) { class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { public: - AsyncContext(FileStream* owner) - : owner_(owner), context_(), is_closing_(false), - record_uma_(false), error_source_(FILE_ERROR_SOURCE_COUNT) { + explicit AsyncContext(const net::BoundNetLog& bound_net_log) + : context_(), is_closing_(false), + record_uma_(false), bound_net_log_(bound_net_log), + error_source_(FILE_ERROR_SOURCE_COUNT) { context_.handler = this; } ~AsyncContext(); @@ -67,13 +82,13 @@ class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { private: virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, - DWORD bytes_read, DWORD error); + DWORD bytes_read, DWORD error) OVERRIDE; - FileStream* owner_; MessageLoopForIO::IOContext context_; CompletionCallback callback_; bool is_closing_; bool record_uma_; + const net::BoundNetLog bound_net_log_; FileErrorSource error_source_; }; @@ -109,8 +124,10 @@ void FileStream::AsyncContext::OnIOCompleted( } int result = static_cast<int>(bytes_read); - if (error && error != ERROR_HANDLE_EOF) - result = RecordAndMapError(error, error_source_, record_uma_); + if (error && error != ERROR_HANDLE_EOF) { + result = RecordAndMapError(error, error_source_, record_uma_, + bound_net_log_); + } if (bytes_read) IncrementOffset(&context->overlapped, bytes_read); @@ -122,22 +139,29 @@ void FileStream::AsyncContext::OnIOCompleted( // FileStream ------------------------------------------------------------ -FileStream::FileStream() - : file_(INVALID_HANDLE_VALUE), +FileStream::FileStream(net::NetLog* net_log) + : file_(base::kInvalidPlatformFileValue), open_flags_(0), auto_closed_(true), - record_uma_(false) { + record_uma_(false), + bound_net_log_(net::BoundNetLog::Make(net_log, + net::NetLog::SOURCE_FILESTREAM)) { + bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL); } -FileStream::FileStream(base::PlatformFile file, int flags) +FileStream::FileStream(base::PlatformFile file, int flags, net::NetLog* net_log) : file_(file), open_flags_(flags), auto_closed_(false), - record_uma_(false) { + record_uma_(false), + bound_net_log_(net::BoundNetLog::Make(net_log, + net::NetLog::SOURCE_FILESTREAM)) { + bound_net_log_.BeginEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL); + // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to // make sure we will perform asynchronous File IO to it. if (flags & base::PLATFORM_FILE_ASYNC) { - async_context_.reset(new AsyncContext(this)); + async_context_.reset(new AsyncContext(bound_net_log_)); MessageLoopForIO::current()->RegisterIOHandler(file_, async_context_.get()); } @@ -146,9 +170,12 @@ FileStream::FileStream(base::PlatformFile file, int flags) FileStream::~FileStream() { if (auto_closed_) Close(); + + bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_ALIVE, NULL); } void FileStream::Close() { + bound_net_log_.AddEvent(net::NetLog::TYPE_FILE_STREAM_CLOSE, NULL); if (file_ != INVALID_HANDLE_VALUE) CancelIo(file_); @@ -156,6 +183,8 @@ void FileStream::Close() { if (file_ != INVALID_HANDLE_VALUE) { CloseHandle(file_); file_ = INVALID_HANDLE_VALUE; + + bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_OPEN, NULL); } } @@ -165,16 +194,27 @@ int FileStream::Open(const FilePath& path, int open_flags) { return ERR_UNEXPECTED; } + bound_net_log_.BeginEvent( + net::NetLog::TYPE_FILE_STREAM_OPEN, + make_scoped_refptr( + new net::NetLogStringParameter("file_name", + path.AsUTF8Unsafe()))); + open_flags_ = open_flags; file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); if (file_ == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); LOG(WARNING) << "Failed to open file: " << error; - return RecordAndMapError(error, FILE_ERROR_SOURCE_OPEN, record_uma_); + int net_error = RecordAndMapError(error, + FILE_ERROR_SOURCE_OPEN, + record_uma_, + bound_net_log_); + bound_net_log_.EndEvent(net::NetLog::TYPE_FILE_STREAM_OPEN, NULL); + return net_error; } if (open_flags_ & base::PLATFORM_FILE_ASYNC) { - async_context_.reset(new AsyncContext(this)); + async_context_.reset(new AsyncContext(bound_net_log_)); if (record_uma_) async_context_->EnableErrorStatistics(); MessageLoopForIO::current()->RegisterIOHandler(file_, @@ -200,7 +240,10 @@ int64 FileStream::Seek(Whence whence, int64 offset) { if (!SetFilePointerEx(file_, distance, &result, move_method)) { DWORD error = GetLastError(); LOG(WARNING) << "SetFilePointerEx failed: " << error; - return RecordAndMapError(error, FILE_ERROR_SOURCE_SEEK, record_uma_); + return RecordAndMapError(error, + FILE_ERROR_SOURCE_SEEK, + record_uma_, + bound_net_log_); } if (async_context_.get()) { async_context_->set_error_source(FILE_ERROR_SOURCE_SEEK); @@ -223,7 +266,10 @@ int64 FileStream::Available() { if (!GetFileSizeEx(file_, &file_size)) { DWORD error = GetLastError(); LOG(WARNING) << "GetFileSizeEx failed: " << error; - return RecordAndMapError(error, FILE_ERROR_SOURCE_GET_SIZE, record_uma_); + return RecordAndMapError(error, + FILE_ERROR_SOURCE_GET_SIZE, + record_uma_, + bound_net_log_); } return file_size.QuadPart - cur_pos; @@ -259,7 +305,10 @@ int FileStream::Read( rv = 0; // Report EOF by returning 0 bytes read. } else { LOG(WARNING) << "ReadFile failed: " << error; - rv = RecordAndMapError(error, FILE_ERROR_SOURCE_READ, record_uma_); + rv = RecordAndMapError(error, + FILE_ERROR_SOURCE_READ, + record_uma_, + bound_net_log_); } } else if (overlapped) { async_context_->IOCompletionIsPending(callback); @@ -318,7 +367,10 @@ int FileStream::Write( rv = ERR_IO_PENDING; } else { LOG(WARNING) << "WriteFile failed: " << error; - rv = RecordAndMapError(error, FILE_ERROR_SOURCE_WRITE, record_uma_); + rv = RecordAndMapError(error, + FILE_ERROR_SOURCE_WRITE, + record_uma_, + bound_net_log_); } } else if (overlapped) { async_context_->IOCompletionIsPending(callback); @@ -342,7 +394,8 @@ int FileStream::Flush() { return RecordAndMapError(GetLastError(), FILE_ERROR_SOURCE_FLUSH, - record_uma_); + record_uma_, + bound_net_log_); } int64 FileStream::Truncate(int64 bytes) { @@ -351,7 +404,7 @@ int64 FileStream::Truncate(int64 bytes) { if (!IsOpen()) return ERR_UNEXPECTED; - // We better be open for reading. + // We'd better be open for writing. DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); // Seek to the position to truncate from. @@ -364,7 +417,10 @@ int64 FileStream::Truncate(int64 bytes) { if (!result) { DWORD error = GetLastError(); LOG(WARNING) << "SetEndOfFile failed: " << error; - return RecordAndMapError(error, FILE_ERROR_SOURCE_SET_EOF, record_uma_); + return RecordAndMapError(error, + FILE_ERROR_SOURCE_SET_EOF, + record_uma_, + bound_net_log_); } // Success. @@ -378,4 +434,28 @@ void FileStream::EnableErrorStatistics() { async_context_->EnableErrorStatistics(); } +void FileStream::SetBoundNetLogSource( + const net::BoundNetLog& owner_bound_net_log) { + if ((owner_bound_net_log.source().id == net::NetLog::Source::kInvalidId) && + (bound_net_log_.source().id == net::NetLog::Source::kInvalidId)) { + // Both |BoundNetLog|s are invalid. + return; + } + + // Should never connect to itself. + DCHECK_NE(bound_net_log_.source().id, owner_bound_net_log.source().id); + + bound_net_log_.AddEvent( + net::NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER, + make_scoped_refptr( + new net::NetLogSourceParameter("source_dependency", + owner_bound_net_log.source()))); + + owner_bound_net_log.AddEvent( + net::NetLog::TYPE_FILE_STREAM_SOURCE, + make_scoped_refptr( + new net::NetLogSourceParameter("source_dependency", + bound_net_log_.source()))); +} + } // namespace net diff --git a/net/base/mock_file_stream.h b/net/base/mock_file_stream.h index be711e1..d8a56d7 100644 --- a/net/base/mock_file_stream.h +++ b/net/base/mock_file_stream.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -20,10 +20,11 @@ namespace testing { class MockFileStream : public net::FileStream { public: - MockFileStream() : forced_error_(net::OK) {} + MockFileStream(net::NetLog* net_log) + : net::FileStream(net_log), forced_error_(net::OK) {} - MockFileStream(base::PlatformFile file, int flags) - : net::FileStream(file, flags), forced_error_(net::OK) {} + MockFileStream(base::PlatformFile file, int flags, net::NetLog* net_log) + : net::FileStream(file, flags, net_log), forced_error_(net::OK) {} // FileStream methods. virtual int Open(const FilePath& path, int open_flags) OVERRIDE; diff --git a/net/base/net_log.h b/net/base/net_log.h index dbcf099..d97c622 100644 --- a/net/base/net_log.h +++ b/net/base/net_log.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -301,7 +301,7 @@ class NET_EXPORT NetLogStringParameter : public NetLog::EventParameters { // NetLogIntegerParameter is a subclass of EventParameters that encapsulates a // single integer parameter. -class NetLogIntegerParameter : public NetLog::EventParameters { +class NET_EXPORT NetLogIntegerParameter : public NetLog::EventParameters { public: // |name| must be a string literal. NetLogIntegerParameter(const char* name, int value) diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h index 9a7e208..a53635f 100644 --- a/net/base/net_log_event_type_list.h +++ b/net/base/net_log_event_type_list.h @@ -1449,3 +1449,43 @@ EVENT_TYPE(HTTP_PIPELINED_CONNECTION_RECEIVED_HEADERS) // "must_close": <True if the pipeline must shut down>, // } EVENT_TYPE(HTTP_PIPELINED_CONNECTION_STREAM_CLOSED) + +// ------------------------------------------------------------------------ +// FileStream events. +// ------------------------------------------------------------------------ + +// This event lasts the lifetime of a file stream. +EVENT_TYPE(FILE_STREAM_ALIVE) + +// This event is created when a file stream is associated with a NetLog source. +// It indicates what file stream event source is used. +// { +// "source_dependency": <Source id of the file stream>, +// } +EVENT_TYPE(FILE_STREAM_SOURCE) + +// This event is created when a file stream is associated with a NetLog source. +// It indicates what event source owns the file stream source. +// { +// "source_dependency": <Source id of the owner of the file stream>, +// } +EVENT_TYPE(FILE_STREAM_BOUND_TO_OWNER) + +// Mark the opening/closing of a file stream. +// The BEGIN event has the following parameters: +// { +// "file_name". +// } +EVENT_TYPE(FILE_STREAM_OPEN) + +// This event is created when a file stream's Close() is called. +// This may occur even when the file is not open. +EVENT_TYPE(FILE_STREAM_CLOSE) + +// This event is created when a file stream operation has an error. +// { +// "operation": open, write, close, etc. +// "os_error": OS-dependent error code. +// "net_error": net::Error code. +// } +EVENT_TYPE(FILE_STREAM_ERROR) diff --git a/net/base/net_log_source_type_list.h b/net/base/net_log_source_type_list.h index d4aac9f..e879485 100644 --- a/net/base/net_log_source_type_list.h +++ b/net/base/net_log_source_type_list.h @@ -26,6 +26,7 @@ SOURCE_TYPE(ASYNC_HOST_RESOLVER_REQUEST, 15) SOURCE_TYPE(UDP_SOCKET, 16) SOURCE_TYPE(CERT_VERIFIER_JOB, 17) SOURCE_TYPE(HTTP_PIPELINED_CONNECTION, 18) +SOURCE_TYPE(FILESTREAM, 19) -SOURCE_TYPE(COUNT, 19) // Always keep this as the last entry. +SOURCE_TYPE(COUNT, 20) // Always keep this as the last entry. diff --git a/net/base/upload_data.cc b/net/base/upload_data.cc index 01eaaca..424939e 100644 --- a/net/base/upload_data.cc +++ b/net/base/upload_data.cc @@ -101,7 +101,7 @@ FileStream* UploadData::Element::NewFileStreamForReading() { // Temporary allow until fix: http://crbug.com/72001. base::ThreadRestrictions::ScopedAllowIO allow_io; - scoped_ptr<FileStream> file(new FileStream()); + scoped_ptr<FileStream> file(new FileStream(NULL)); int64 rv = file->Open(file_path_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); if (rv != OK) { diff --git a/net/net.gyp b/net/net.gyp index 6c301a3..46327a1 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -111,6 +111,8 @@ 'base/file_stream_metrics.h', 'base/file_stream_metrics_posix.cc', 'base/file_stream_metrics_win.cc', + 'base/file_stream_net_log_parameters.cc', + 'base/file_stream_net_log_parameters.h', 'base/file_stream_posix.cc', 'base/file_stream_win.cc', 'base/filter.cc', diff --git a/net/tools/dump_cache/dump_files.cc b/net/tools/dump_cache/dump_files.cc index 5d2975a..4fab6f2 100644 --- a/net/tools/dump_cache/dump_files.cc +++ b/net/tools/dump_cache/dump_files.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,7 +26,7 @@ const wchar_t kDataPrefix[] = L"data_"; // Reads the |header_size| bytes from the beginning of file |name|. bool ReadHeader(const std::wstring& name, char* header, int header_size) { - net::FileStream file; + net::FileStream file(NULL); file.Open(FilePath::FromWStringHack(name), base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); if (!file.IsOpen()) { diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc index e42a938..d8187ab 100644 --- a/net/url_request/url_request_file_job.cc +++ b/net/url_request/url_request_file_job.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -86,6 +86,7 @@ URLRequestFileJob::URLRequestFileJob(URLRequest* request, const FilePath& file_path) : URLRequestJob(request), file_path_(file_path), + stream_(NULL), is_directory_(false), remaining_bytes_(0) { } diff --git a/webkit/blob/blob_url_request_job.cc b/webkit/blob/blob_url_request_job.cc index e195f24..46ffd21 100644 --- a/webkit/blob/blob_url_request_job.cc +++ b/webkit/blob/blob_url_request_job.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -327,7 +327,7 @@ void BlobURLRequestJob::DidOpen(base::PlatformFileError rv, } DCHECK(!stream_.get()); - stream_.reset(new net::FileStream(file.ReleaseValue(), kFileOpenFlags)); + stream_.reset(new net::FileStream(file.ReleaseValue(), kFileOpenFlags, NULL)); const BlobData::Item& item = blob_data_->items().at(item_index_); { diff --git a/webkit/fileapi/file_system_url_request_job.cc b/webkit/fileapi/file_system_url_request_job.cc index d01dc40..342edae 100644 --- a/webkit/fileapi/file_system_url_request_job.cc +++ b/webkit/fileapi/file_system_url_request_job.cc @@ -267,7 +267,7 @@ void FileSystemURLRequestJob::DidOpen(base::PlatformFileError error_code, return; } - stream_.reset(new net::FileStream(file.ReleaseValue(), kFileFlags)); + stream_.reset(new net::FileStream(file.ReleaseValue(), kFileFlags, NULL)); remaining_bytes_ = byte_range_.last_byte_position() - byte_range_.first_byte_position() + 1; diff --git a/webkit/fileapi/file_writer_delegate.cc b/webkit/fileapi/file_writer_delegate.cc index d28ef66..3733b1b 100644 --- a/webkit/fileapi/file_writer_delegate.cc +++ b/webkit/fileapi/file_writer_delegate.cc @@ -118,9 +118,11 @@ void FileWriterDelegate::OnGetFileInfoAndCallStartUpdate( if (kint64max - overlap > allowed_bytes_growth) allowed_bytes_to_write_ += overlap; size_ = file_info.size; - file_stream_.reset(new net::FileStream(file_, + file_stream_.reset(new net::FileStream( + file_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | - base::PLATFORM_FILE_ASYNC)); + base::PLATFORM_FILE_ASYNC, + NULL)); request_->Start(); } diff --git a/webkit/glue/webfileutilities_impl.cc b/webkit/glue/webfileutilities_impl.cc index 7548d70..668062f 100644 --- a/webkit/glue/webfileutilities_impl.cc +++ b/webkit/glue/webfileutilities_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -127,7 +127,7 @@ long long WebFileUtilitiesImpl::seekFile(base::PlatformFile handle, int origin) { if (handle == base::kInvalidPlatformFileValue) return -1; - net::FileStream file_stream(handle, 0); + net::FileStream file_stream(handle, 0, NULL); return file_stream.Seek(static_cast<net::Whence>(origin), offset); } @@ -135,7 +135,7 @@ bool WebFileUtilitiesImpl::truncateFile(base::PlatformFile handle, long long offset) { if (handle == base::kInvalidPlatformFileValue || offset < 0) return false; - net::FileStream file_stream(handle, base::PLATFORM_FILE_WRITE); + net::FileStream file_stream(handle, base::PLATFORM_FILE_WRITE, NULL); return file_stream.Truncate(offset) >= 0; } @@ -146,7 +146,7 @@ int WebFileUtilitiesImpl::readFromFile(base::PlatformFile handle, return -1; std::string buffer; buffer.resize(length); - net::FileStream file_stream(handle, base::PLATFORM_FILE_READ); + net::FileStream file_stream(handle, base::PLATFORM_FILE_READ, NULL); return file_stream.Read(data, length, net::CompletionCallback()); } @@ -155,7 +155,7 @@ int WebFileUtilitiesImpl::writeToFile(base::PlatformFile handle, int length) { if (handle == base::kInvalidPlatformFileValue || !data || length <= 0) return -1; - net::FileStream file_stream(handle, base::PLATFORM_FILE_WRITE); + net::FileStream file_stream(handle, base::PLATFORM_FILE_WRITE, NULL); return file_stream.Write(data, length, net::CompletionCallback()); } diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index 102f7ac..1dd138e 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -190,6 +190,7 @@ class RequestProxy : public net::URLRequest::Delegate, // Takes ownership of the params. RequestProxy() : download_to_file_(false), + file_stream_(NULL), buf_(new net::IOBuffer(kDataSize)), last_upload_position_(0) { } |