| // 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/dns/serial_worker.h" |
| |
| #include "base/bind.h" |
| #include "base/location.h" |
| #include "base/task/post_task.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| |
| namespace net { |
| |
| SerialWorker::SerialWorker() : state_(IDLE), weak_factory_(this) {} |
| |
| SerialWorker::~SerialWorker() = default; |
| |
| void SerialWorker::WorkNow() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| switch (state_) { |
| case IDLE: |
| // We are posting weak pointer to OnWorkJobFinished to avoid leak when |
| // PostTaskWithTraitsAndReply fails to post task back to the original |
| // task runner. In this case the callback is not destroyed, and the |
| // weak reference allows SerialWorker instance to be deleted. |
| base::PostTaskWithTraitsAndReply( |
| FROM_HERE, |
| {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, |
| base::BindOnce(&SerialWorker::DoWork, this), |
| base::BindOnce(&SerialWorker::OnWorkJobFinished, |
| weak_factory_.GetWeakPtr())); |
| state_ = WORKING; |
| return; |
| case WORKING: |
| // Remember to re-read after |DoRead| finishes. |
| state_ = PENDING; |
| return; |
| case CANCELLED: |
| case PENDING: |
| return; |
| default: |
| NOTREACHED() << "Unexpected state " << state_; |
| } |
| } |
| |
| void SerialWorker::Cancel() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| state_ = CANCELLED; |
| } |
| |
| void SerialWorker::OnWorkJobFinished() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| switch (state_) { |
| case CANCELLED: |
| return; |
| case WORKING: |
| state_ = IDLE; |
| this->OnWorkFinished(); |
| return; |
| case PENDING: |
| state_ = IDLE; |
| WorkNow(); |
| return; |
| default: |
| NOTREACHED() << "Unexpected state " << state_; |
| } |
| } |
| |
| } // namespace net |