123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- // Copyright 2013 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.
- #ifndef TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
- #define TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
- #include <memory>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/check_op.h"
- #include "base/location.h"
- #include "base/macros.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/weak_ptr.h"
- #include "base/threading/thread_task_runner_handle.h"
- namespace base {
- class SingleThreadTaskRunner;
- } // namespace base
- namespace forwarder2 {
- // Helper template class to be used in the following case:
- // * T is the type of an object that implements some work through an internal
- // or worker thread.
- // * T wants the internal thread to invoke deletion of its own instance, on
- // the thread where the instance was created.
- //
- // To make this easier, do something like:
- // 1) Add a SelfDeleteHelper<T> member to your class T, and default-initialize
- // it in its constructor.
- // 2) In the internal thread, to trigger self-deletion, call the
- // MaybeDeleteSoon() method on this member.
- //
- // MaybeDeleteSoon() posts a task on the message loop where the T instance was
- // created to delete it. The task will be safely ignored if the instance is
- // otherwise deleted.
- //
- // Usage example:
- // class Object {
- // public:
- // using ErrorCallback = base::OnceCallback<void (std::unique_ptr<Object>)>;
- //
- // Object(ErrorCallback error_callback)
- // : self_deleter_helper_(this, std::move(error_callback)) {
- // }
- //
- // void StartWork() {
- // // Post a callback to DoSomethingOnWorkerThread() below to another
- // // thread.
- // }
- //
- // void DoSomethingOnWorkerThread() {
- // ...
- // if (error_happened)
- // self_deleter_helper_.MaybeDeleteSoon();
- // }
- //
- // private:
- // SelfDeleterHelper<MySelfDeletingClass> self_deleter_helper_;
- // };
- //
- // class ObjectOwner {
- // public:
- // ObjectOwner()
- // : object_(new Object(base::BindOnce(&ObjectOwner::DeleteObjectOnError,
- // base::Unretained(this))) {
- // // To keep this example simple base::Unretained(this) is used above but
- // // note that in a real world scenario the client would have to make sure
- // // that the ObjectOwner instance is still alive when
- // // DeleteObjectOnError() gets called below. This can be achieved by
- // // using a WeakPtr<ObjectOwner> for instance.
- // }
- //
- // void StartWork() {
- // object_->StartWork();
- // }
- //
- // private:
- // void DeleteObjectOnError(std::unique_ptr<Object> object) {
- // DCHECK(thread_checker_.CalledOnValidThread());
- // DCHECK_EQ(object_, object);
- // // Do some extra work with |object| before it gets deleted...
- // object_.reset();
- // ignore_result(object.release());
- // }
- //
- // base::ThreadChecker thread_checker_;
- // std::unique_ptr<Object> object_;
- // };
- //
- template <typename T>
- class SelfDeleterHelper {
- public:
- using DeletionCallback = base::OnceCallback<void(std::unique_ptr<T>)>;
- SelfDeleterHelper(T* self_deleting_object, DeletionCallback deletion_callback)
- : construction_runner_(base::ThreadTaskRunnerHandle::Get()),
- self_deleting_object_(self_deleting_object),
- deletion_callback_(std::move(deletion_callback)) {}
- ~SelfDeleterHelper() {
- DCHECK(construction_runner_->RunsTasksInCurrentSequence());
- }
- void MaybeSelfDeleteSoon() {
- DCHECK(!construction_runner_->RunsTasksInCurrentSequence());
- construction_runner_->PostTask(
- FROM_HERE, base::BindOnce(&SelfDeleterHelper::SelfDelete,
- weak_ptr_factory_.GetWeakPtr()));
- }
- private:
- void SelfDelete() {
- DCHECK(construction_runner_->RunsTasksInCurrentSequence());
- std::move(deletion_callback_).Run(base::WrapUnique(self_deleting_object_));
- }
- const scoped_refptr<base::SingleThreadTaskRunner> construction_runner_;
- T* const self_deleting_object_;
- DeletionCallback deletion_callback_;
- // WeakPtrFactory's documentation says:
- // Member variables should appear before the WeakPtrFactory, to ensure
- // that any WeakPtrs to Controller are invalidated before its members
- // variable's destructors are executed, rendering them invalid.
- base::WeakPtrFactory<SelfDeleterHelper<T>> weak_ptr_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(SelfDeleterHelper);
- };
- } // namespace forwarder2
- #endif // TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
|