 Chromium Code Reviews
 Chromium Code Reviews Issue 9333003:
  Use FILE thread for disk operations in TraceSubscriberStdio  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src/
    
  
    Issue 9333003:
  Use FILE thread for disk operations in TraceSubscriberStdio  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src/| Index: content/browser/trace_subscriber_stdio.cc | 
| =================================================================== | 
| --- content/browser/trace_subscriber_stdio.cc (revision 120972) | 
| +++ content/browser/trace_subscriber_stdio.cc (working copy) | 
| @@ -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(); | 
| + } | 
| -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 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(); | 
| + } | 
| } | 
| -} | 
| -void TraceSubscriberStdio::CloseFile() { | 
| - if (file_) { | 
| - fclose(file_); | 
| - file_ = 0; | 
| + 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 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( | 
| + "TraceSubscriberStdio", FROM_HERE, | 
| 
joth
2012/02/08 18:37:36
Let's extract a constant for the token, else it wo
 
Iain Merrick
2012/02/08 18:57:06
__FILE__ is a great idea, done.
 | 
| + 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( | 
| + "TraceSubscriberStdio", 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( | 
| + "TraceSubscriberStdio", 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 | 
| + |