Index: net/log/file_net_log_observer.cc |
diff --git a/net/log/file_net_log_observer.cc b/net/log/file_net_log_observer.cc |
index 0c05f9e1e2f3a239090d9e3024231a09b44b343e..f00785d0bdde07557f611b9f5fd0a106f46c730b 100644 |
--- a/net/log/file_net_log_observer.cc |
+++ b/net/log/file_net_log_observer.cc |
@@ -16,10 +16,10 @@ |
#include "base/files/file_util.h" |
#include "base/json/json_writer.h" |
#include "base/logging.h" |
-#include "base/single_thread_task_runner.h" |
+#include "base/sequenced_task_runner.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/synchronization/lock.h" |
-#include "base/threading/thread.h" |
+#include "base/task_scheduler/post_task.h" |
#include "base/values.h" |
#include "net/log/net_log_capture_mode.h" |
#include "net/log/net_log_entry.h" |
@@ -28,10 +28,21 @@ |
namespace { |
-// Number of events that can build up in |write_queue_| before file thread |
-// is triggered to drain the queue. |
+// Number of events that can build up in |write_queue_| before a task is posted |
+// to the file task runner to flush them to disk. |
const int kNumWriteQueueEvents = 15; |
+scoped_refptr<base::SequencedTaskRunner> CreateFileTaskRunner() { |
+ // The tasks posted to this sequenced task runner do synchronous File I/O for |
+ // the purposes of writing NetLog files. |
+ // |
+ // These intentionally block shutdown to ensure the log file has finished |
+ // being written. |
+ return base::CreateSequencedTaskRunnerWithTraits( |
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE, |
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
+} |
+ |
} // namespace |
namespace net { |
@@ -41,14 +52,14 @@ using EventQueue = std::queue<std::unique_ptr<std::string>>; |
// WriteQueue receives events from FileNetLogObserver on the main thread and |
// holds them in a queue until they are drained from the queue and written to |
-// file on the file thread. |
+// file on the file task runner. |
// |
// WriteQueue contains the resources shared between the main thread and the |
-// file thread. |lock_| must be acquired to read or write to |queue_| and |
+// file task runner. |lock_| must be acquired to read or write to |queue_| and |
// |memory_|. |
// |
// WriteQueue is refcounted and should be destroyed once all events on the |
-// file thread have finished executing. |
+// file task runner have finished executing. |
class FileNetLogObserver::WriteQueue |
: public base::RefCountedThreadSafe<WriteQueue> { |
public: |
@@ -73,17 +84,17 @@ class FileNetLogObserver::WriteQueue |
~WriteQueue(); |
- // Queue of events to be written shared between main thread and file thread. |
- // Main thread adds events to the queue and the file thread drains them and |
- // writes the events to file. |
+ // Queue of events to be written, shared between main thread and file task |
+ // runner. Main thread adds events to the queue and the file task runner |
+ // drains them and writes the events to file. |
// |
// |lock_| must be acquired to read or write to this. |
EventQueue queue_; |
// Tracks how much memory is being used by the virtual write queue. |
// Incremented in AddEntryToQueue() when events are added to the |
- // buffer, and decremented when SwapQueue() is called and the file thread's |
- // local queue is swapped with the shared write queue. |
+ // buffer, and decremented when SwapQueue() is called and the file task |
+ // runner's local queue is swapped with the shared write queue. |
// |
// |lock_| must be acquired to read or write to this. |
size_t memory_; |
@@ -95,14 +106,14 @@ class FileNetLogObserver::WriteQueue |
// Protects access to |queue_| and |memory_|. |
// |
// A lock is necessary because |queue_| and |memory_| are shared between the |
- // file thread and the main thread. NetLog's lock protects OnAddEntry(), |
+ // file task runner and the main thread. NetLog's lock protects OnAddEntry(), |
// which calls AddEntryToQueue(), but it does not protect access to the |
// observer's member variables. Thus, a race condition exists if a thread is |
- // calling OnAddEntry() at the same time that the file thread is accessing |
- // |memory_| and |queue_| to write events to file. The |queue_| and |memory_| |
- // counter are necessary to bound the amount of memory that is used for the |
- // queue in the event that the file thread lags significantly behind the main |
- // thread in writing events to file. |
+ // calling OnAddEntry() at the same time that the file task runner is |
+ // accessing |memory_| and |queue_| to write events to file. The |queue_| and |
+ // |memory_| counter are necessary to bound the amount of memory that is used |
+ // for the queue in the event that the file task runner lags significantly |
+ // behind the main thread in writing events to file. |
base::Lock lock_; |
DISALLOW_COPY_AND_ASSIGN(WriteQueue); |
@@ -138,14 +149,15 @@ class FileNetLogObserver::FileWriter { |
// This implementation of FileWriter is used when the observer is in bounded |
// mode. |
// BoundedFileWriter can be constructed on any thread, and afterwards is only |
-// accessed on the file thread. |
+// accessed on the file task runner. |
class FileNetLogObserver::BoundedFileWriter |
: public FileNetLogObserver::FileWriter { |
public: |
- BoundedFileWriter(const base::FilePath& directory, |
- size_t max_file_size, |
- size_t total_num_files, |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ BoundedFileWriter( |
+ const base::FilePath& directory, |
+ size_t max_file_size, |
+ size_t total_num_files, |
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner); |
mmenke
2017/07/07 15:32:59
I think scoped_refptr<base::SequencedTaskRunner> +
eroman
2017/07/07 21:03:08
I switched to const scoped_refptr<> throughout, be
|
~BoundedFileWriter() override; |
@@ -180,8 +192,8 @@ class FileNetLogObserver::BoundedFileWriter |
// the constant file. |
const size_t max_file_size_; |
- // Task runner from the file thread. |
- const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ // Task runner for doing file operations. |
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_; |
DISALLOW_COPY_AND_ASSIGN(BoundedFileWriter); |
}; |
@@ -189,12 +201,13 @@ class FileNetLogObserver::BoundedFileWriter |
// This implementation of FileWriter is used when the observer is in unbounded |
// mode. |
// UnboundedFileWriter can be constructed on any thread, and afterwards is only |
-// accessed on the file thread. |
+// accessed on the file task runner. |
class FileNetLogObserver::UnboundedFileWriter |
: public FileNetLogObserver::FileWriter { |
public: |
- UnboundedFileWriter(const base::FilePath& path, |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ UnboundedFileWriter( |
+ const base::FilePath& path, |
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner); |
~UnboundedFileWriter() override; |
@@ -211,19 +224,22 @@ class FileNetLogObserver::UnboundedFileWriter |
// Is set to true after the first event is written to the log file. |
bool first_event_written_; |
- // Task runner from the file thread. |
- const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ // Task runner for doing file operations. |
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_; |
DISALLOW_COPY_AND_ASSIGN(UnboundedFileWriter); |
}; |
std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateBounded( |
- scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, |
const base::FilePath& directory, |
size_t max_total_size, |
size_t total_num_files, |
std::unique_ptr<base::Value> constants) { |
DCHECK_GT(total_num_files, 0u); |
+ |
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner = |
+ CreateFileTaskRunner(); |
+ |
// The BoundedFileWriter uses a soft limit to write events to file that allows |
// the size of the file to exceed the limit, but the WriteQueue uses a hard |
// limit which the size of |WriteQueue::queue_| cannot exceed. Thus, the |
@@ -248,9 +264,11 @@ std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateBounded( |
} |
std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateUnbounded( |
- scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, |
const base::FilePath& log_path, |
std::unique_ptr<base::Value> constants) { |
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner = |
+ CreateFileTaskRunner(); |
+ |
std::unique_ptr<FileWriter> file_writer( |
new UnboundedFileWriter(log_path, file_task_runner)); |
@@ -268,9 +286,9 @@ FileNetLogObserver::~FileNetLogObserver() { |
net_log()->DeprecatedRemoveObserver(this); |
file_task_runner_->PostTask( |
FROM_HERE, base::Bind(&FileNetLogObserver::FileWriter::DeleteAllFiles, |
- base::Unretained(file_writer_))); |
+ base::Unretained(file_writer_.get()))); |
} |
- file_task_runner_->DeleteSoon(FROM_HERE, file_writer_); |
+ file_task_runner_->DeleteSoon(FROM_HERE, file_writer_.release()); |
} |
void FileNetLogObserver::StartObserving(NetLog* net_log, |
@@ -283,9 +301,10 @@ void FileNetLogObserver::StopObserving(std::unique_ptr<base::Value> polled_data, |
net_log()->DeprecatedRemoveObserver(this); |
file_task_runner_->PostTaskAndReply( |
- FROM_HERE, base::Bind(&FileNetLogObserver::FileWriter::FlushThenStop, |
- base::Unretained(file_writer_), write_queue_, |
- base::Passed(&polled_data)), |
+ FROM_HERE, |
+ base::Bind(&FileNetLogObserver::FileWriter::FlushThenStop, |
+ base::Unretained(file_writer_.get()), write_queue_, |
+ base::Passed(&polled_data)), |
callback); |
} |
@@ -298,31 +317,32 @@ void FileNetLogObserver::OnAddEntry(const NetLogEntry& entry) { |
size_t queue_size = write_queue_->AddEntryToQueue(std::move(json)); |
- // If events build up in |write_queue_|, trigger the file thread to drain |
+ // If events build up in |write_queue_|, trigger the file task runner to drain |
// the queue. Because only 1 item is added to the queue at a time, if |
// queue_size > kNumWriteQueueEvents a task has already been posted, or will |
// be posted. |
if (queue_size == kNumWriteQueueEvents) { |
file_task_runner_->PostTask( |
- FROM_HERE, base::Bind(&FileNetLogObserver::FileWriter::Flush, |
- base::Unretained(file_writer_), write_queue_)); |
+ FROM_HERE, |
+ base::Bind(&FileNetLogObserver::FileWriter::Flush, |
+ base::Unretained(file_writer_.get()), write_queue_)); |
} |
} |
FileNetLogObserver::FileNetLogObserver( |
- scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, |
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner, |
std::unique_ptr<FileWriter> file_writer, |
scoped_refptr<WriteQueue> write_queue, |
std::unique_ptr<base::Value> constants) |
: file_task_runner_(std::move(file_task_runner)), |
write_queue_(std::move(write_queue)), |
- file_writer_(file_writer.release()) { |
+ file_writer_(std::move(file_writer)) { |
if (!constants) |
constants = GetNetConstants(); |
file_task_runner_->PostTask( |
- FROM_HERE, |
- base::Bind(&FileNetLogObserver::FileWriter::Initialize, |
- base::Unretained(file_writer_), base::Passed(&constants))); |
+ FROM_HERE, base::Bind(&FileNetLogObserver::FileWriter::Initialize, |
+ base::Unretained(file_writer_.get()), |
+ base::Passed(&constants))); |
} |
FileNetLogObserver::WriteQueue::WriteQueue(size_t memory_max) |
@@ -367,7 +387,7 @@ FileNetLogObserver::BoundedFileWriter::BoundedFileWriter( |
const base::FilePath& directory, |
size_t max_file_size, |
size_t total_num_files, |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) |
: directory_(directory), |
total_num_files_(total_num_files), |
current_file_idx_(0), |
@@ -473,7 +493,7 @@ void FileNetLogObserver::BoundedFileWriter::DeleteAllFiles() { |
FileNetLogObserver::UnboundedFileWriter::UnboundedFileWriter( |
const base::FilePath& path, |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) |
: file_path_(path), task_runner_(task_runner) {} |
FileNetLogObserver::UnboundedFileWriter::~UnboundedFileWriter() {} |