self_deleter_helper.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
  5. #define TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/callback.h"
  9. #include "base/check_op.h"
  10. #include "base/location.h"
  11. #include "base/macros.h"
  12. #include "base/memory/ptr_util.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/threading/thread_task_runner_handle.h"
  16. namespace base {
  17. class SingleThreadTaskRunner;
  18. } // namespace base
  19. namespace forwarder2 {
  20. // Helper template class to be used in the following case:
  21. // * T is the type of an object that implements some work through an internal
  22. // or worker thread.
  23. // * T wants the internal thread to invoke deletion of its own instance, on
  24. // the thread where the instance was created.
  25. //
  26. // To make this easier, do something like:
  27. // 1) Add a SelfDeleteHelper<T> member to your class T, and default-initialize
  28. // it in its constructor.
  29. // 2) In the internal thread, to trigger self-deletion, call the
  30. // MaybeDeleteSoon() method on this member.
  31. //
  32. // MaybeDeleteSoon() posts a task on the message loop where the T instance was
  33. // created to delete it. The task will be safely ignored if the instance is
  34. // otherwise deleted.
  35. //
  36. // Usage example:
  37. // class Object {
  38. // public:
  39. // using ErrorCallback = base::OnceCallback<void (std::unique_ptr<Object>)>;
  40. //
  41. // Object(ErrorCallback error_callback)
  42. // : self_deleter_helper_(this, std::move(error_callback)) {
  43. // }
  44. //
  45. // void StartWork() {
  46. // // Post a callback to DoSomethingOnWorkerThread() below to another
  47. // // thread.
  48. // }
  49. //
  50. // void DoSomethingOnWorkerThread() {
  51. // ...
  52. // if (error_happened)
  53. // self_deleter_helper_.MaybeDeleteSoon();
  54. // }
  55. //
  56. // private:
  57. // SelfDeleterHelper<MySelfDeletingClass> self_deleter_helper_;
  58. // };
  59. //
  60. // class ObjectOwner {
  61. // public:
  62. // ObjectOwner()
  63. // : object_(new Object(base::BindOnce(&ObjectOwner::DeleteObjectOnError,
  64. // base::Unretained(this))) {
  65. // // To keep this example simple base::Unretained(this) is used above but
  66. // // note that in a real world scenario the client would have to make sure
  67. // // that the ObjectOwner instance is still alive when
  68. // // DeleteObjectOnError() gets called below. This can be achieved by
  69. // // using a WeakPtr<ObjectOwner> for instance.
  70. // }
  71. //
  72. // void StartWork() {
  73. // object_->StartWork();
  74. // }
  75. //
  76. // private:
  77. // void DeleteObjectOnError(std::unique_ptr<Object> object) {
  78. // DCHECK(thread_checker_.CalledOnValidThread());
  79. // DCHECK_EQ(object_, object);
  80. // // Do some extra work with |object| before it gets deleted...
  81. // object_.reset();
  82. // ignore_result(object.release());
  83. // }
  84. //
  85. // base::ThreadChecker thread_checker_;
  86. // std::unique_ptr<Object> object_;
  87. // };
  88. //
  89. template <typename T>
  90. class SelfDeleterHelper {
  91. public:
  92. using DeletionCallback = base::OnceCallback<void(std::unique_ptr<T>)>;
  93. SelfDeleterHelper(T* self_deleting_object, DeletionCallback deletion_callback)
  94. : construction_runner_(base::ThreadTaskRunnerHandle::Get()),
  95. self_deleting_object_(self_deleting_object),
  96. deletion_callback_(std::move(deletion_callback)) {}
  97. ~SelfDeleterHelper() {
  98. DCHECK(construction_runner_->RunsTasksInCurrentSequence());
  99. }
  100. void MaybeSelfDeleteSoon() {
  101. DCHECK(!construction_runner_->RunsTasksInCurrentSequence());
  102. construction_runner_->PostTask(
  103. FROM_HERE, base::BindOnce(&SelfDeleterHelper::SelfDelete,
  104. weak_ptr_factory_.GetWeakPtr()));
  105. }
  106. private:
  107. void SelfDelete() {
  108. DCHECK(construction_runner_->RunsTasksInCurrentSequence());
  109. std::move(deletion_callback_).Run(base::WrapUnique(self_deleting_object_));
  110. }
  111. const scoped_refptr<base::SingleThreadTaskRunner> construction_runner_;
  112. T* const self_deleting_object_;
  113. DeletionCallback deletion_callback_;
  114. // WeakPtrFactory's documentation says:
  115. // Member variables should appear before the WeakPtrFactory, to ensure
  116. // that any WeakPtrs to Controller are invalidated before its members
  117. // variable's destructors are executed, rendering them invalid.
  118. base::WeakPtrFactory<SelfDeleterHelper<T>> weak_ptr_factory_{this};
  119. DISALLOW_COPY_AND_ASSIGN(SelfDeleterHelper);
  120. };
  121. } // namespace forwarder2
  122. #endif // TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_