diff options
author | husky@chromium.org <husky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-24 04:17:06 +0000 |
---|---|---|
committer | husky@chromium.org <husky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-24 04:17:06 +0000 |
commit | b77226e27cab2828e1638a978864442dd336a73e (patch) | |
tree | 190bad928416e69b85b5a930dac33954b9c2fb8a /content/browser/trace_subscriber_stdio.cc | |
parent | b07cdbcc2fd4044902f1542df9501b49c5f94786 (diff) | |
download | chromium_src-b77226e27cab2828e1638a978864442dd336a73e.zip chromium_src-b77226e27cab2828e1638a978864442dd336a73e.tar.gz chromium_src-b77226e27cab2828e1638a978864442dd336a73e.tar.bz2 |
Use SequencedWorkerPool for disk operations in TraceSubscriberStdio.
This class was hitting a ThreadRestrictions assert because it called
OpenFile on the UI thread. To reduce unnecessary copying, I've changed
the OnTraceDataCollected argument from std::string to RefCountedString.
Second attempt (originally committed in 123140, reverted in 123146).
Added DISALLOW_COPY_AND_ASSIGN to fix Windows compilation error.
BUG=None
TEST=content_unittests
Review URL: http://codereview.chromium.org/9443020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123433 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/trace_subscriber_stdio.cc')
-rw-r--r-- | content/browser/trace_subscriber_stdio.cc | 116 |
1 files changed, 75 insertions, 41 deletions
diff --git a/content/browser/trace_subscriber_stdio.cc b/content/browser/trace_subscriber_stdio.cc index 0ecd51e..028404c 100644 --- a/content/browser/trace_subscriber_stdio.cc +++ b/content/browser/trace_subscriber_stdio.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. @@ -6,60 +6,94 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/threading/sequenced_worker_pool.h" +#include "content/public/browser/browser_thread.h" -TraceSubscriberStdio::TraceSubscriberStdio() : file_(0) { -} +namespace content { -TraceSubscriberStdio::TraceSubscriberStdio(const FilePath& path) : file_(0) { - OpenFile(path); -} +// All method calls on this class are done on a SequencedWorkerPool thread. +class TraceSubscriberStdioImpl + : public base::RefCountedThreadSafe<TraceSubscriberStdioImpl> { + public: + explicit TraceSubscriberStdioImpl(const FilePath& path) + : path_(path), + file_(0) {} -TraceSubscriberStdio::~TraceSubscriberStdio() { - CloseFile(); -} + ~TraceSubscriberStdioImpl() { + CloseFile(); + } + + void OnStart() { + DCHECK(!file_); + file_ = file_util::OpenFile(path_, "w+"); + if (IsValid()) { + LOG(INFO) << "Logging performance trace to file: " << path_.value(); + trace_buffer_.SetOutputCallback( + base::Bind(&TraceSubscriberStdioImpl::Write, this)); + trace_buffer_.Start(); + } else { + LOG(ERROR) << "Failed to open performance trace file: " << path_.value(); + } + } -bool TraceSubscriberStdio::OpenFile(const FilePath& path) { - LOG(INFO) << "Logging performance trace to file: " << path.value(); - CloseFile(); - file_ = file_util::OpenFile(path, "w+"); - if (IsValid()) { - trace_buffer_.SetOutputCallback(base::Bind(&TraceSubscriberStdio::Write, - base::Unretained(this))); - trace_buffer_.Start(); - return true; - } else { - LOG(ERROR) << "Failed to open performance trace file: " << path.value(); - return false; + void OnData(const scoped_refptr<base::RefCountedString>& data_ptr) { + trace_buffer_.AddFragment(data_ptr->data()); + } + + void OnEnd() { + trace_buffer_.Finish(); + CloseFile(); + } + + private: + bool IsValid() { + return file_ && (0 == ferror(file_)); + } + + void CloseFile() { + if (file_) { + fclose(file_); + file_ = 0; + } } -} -void TraceSubscriberStdio::CloseFile() { - if (file_) { - fclose(file_); - file_ = 0; + void Write(const std::string& output_str) { + if (IsValid()) { + size_t written = fwrite(output_str.data(), 1, output_str.size(), file_); + if (written != output_str.size()) { + LOG(ERROR) << "Error " << ferror(file_) << " in fwrite() to trace file"; + CloseFile(); + } + } } + + FilePath path_; + FILE* file_; + base::debug::TraceResultBuffer trace_buffer_; +}; + +TraceSubscriberStdio::TraceSubscriberStdio(const FilePath& path) + : impl_(new TraceSubscriberStdioImpl(path)) { + BrowserThread::PostBlockingPoolSequencedTask( + __FILE__, FROM_HERE, + base::Bind(&TraceSubscriberStdioImpl::OnStart, impl_.get())); } -bool TraceSubscriberStdio::IsValid() { - return file_ && (0 == ferror(file_)); +TraceSubscriberStdio::~TraceSubscriberStdio() { } void TraceSubscriberStdio::OnEndTracingComplete() { - trace_buffer_.Finish(); - CloseFile(); + BrowserThread::PostBlockingPoolSequencedTask( + __FILE__, FROM_HERE, + base::Bind(&TraceSubscriberStdioImpl::OnEnd, impl_.get())); } void TraceSubscriberStdio::OnTraceDataCollected( - const std::string& trace_fragment) { - trace_buffer_.AddFragment(trace_fragment); + const scoped_refptr<base::RefCountedString>& data_ptr) { + BrowserThread::PostBlockingPoolSequencedTask( + __FILE__, FROM_HERE, + base::Bind(&TraceSubscriberStdioImpl::OnData, impl_.get(), data_ptr)); } -void TraceSubscriberStdio::Write(const std::string& output_str) { - if (IsValid()) { - size_t written = fwrite(output_str.data(), 1, output_str.size(), file_); - if (written != output_str.size()) { - LOG(ERROR) << "Error " << ferror(file_) << " when writing to trace file"; - CloseFile(); - } - } -} +} // namespace content + |