// Copyright 2011 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/threading/post_task_and_reply_impl.h" #include <utility> #include "base/check_op.h" #include "base/debug/leak_annotations.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool/thread_pool_instance.h" namespace base::internal { PostTaskAndReplyRelay::PostTaskAndReplyRelay( const Location& from_here, OnceClosure task, OnceClosure reply, scoped_refptr<SequencedTaskRunner> reply_task_runner) : … { … } PostTaskAndReplyRelay::PostTaskAndReplyRelay(PostTaskAndReplyRelay&&) = default; // It is important that `reply_` always be deleted on the origin sequence // (`reply_task_runner_`) since its destructor can be affine to it. More // sutbly, it is also important that `task_` be destroyed on the origin // sequence when it fails to run. This is because `task_` can own state which // is affine to `reply_task_runner_` and was intended to be handed to // `reply_`, e.g. https://crbug.com/829122. Since `task_` already needs to // support deletion on the origin sequence (since the initial PostTask can // always fail), it's safer to delete it there when PostTask succeeds but // `task_` is later prevented from running. // // PostTaskAndReplyRelay's move semantics along with logic in this destructor // enforce the above semantics in all the following cases : // 1) Posting `task_` fails right away on the origin sequence: // a) `reply_task_runner_` is null (i.e. during late shutdown); // b) `reply_task_runner_` is set. // 2) ~PostTaskAndReplyRelay() runs on the destination sequence: // a) RunTaskAndPostReply() is cancelled before running; // b) RunTaskAndPostReply() is skipped on shutdown; // c) Posting RunReply() fails. // 3) ~PostTaskAndReplyRelay() runs on the origin sequence: // a) RunReply() is cancelled before running; // b) RunReply() is skipped on shutdown; // c) The DeleteSoon() posted by (2) runs. // 4) ~PostTaskAndReplyRelay() should no-op: // a) This relay was moved to another relay instance; // b) RunReply() ran and completed this relay's mandate. PostTaskAndReplyRelay::~PostTaskAndReplyRelay() { … } } // namespace base::internal