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.
5 #ifndef TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
6 #define TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
8 #include "base/basictypes.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/message_loop/message_loop_proxy.h"
20 class SingleThreadTaskRunner
;
24 namespace forwarder2
{
26 // Helper template class to be used in the following case:
27 // * T is the type of an object that implements some work through an internal
29 // * T wants the internal thread to invoke deletion of its own instance, on
30 // the thread where the instance was created.
32 // To make this easier, do something like:
33 // 1) Add a SelfDeleteHelper<T> member to your class T, and default-initialize
34 // it in its constructor.
35 // 2) In the internal thread, to trigger self-deletion, call the
36 // MaybeDeleteSoon() method on this member.
38 // MaybeDeleteSoon() posts a task on the message loop where the T instance was
39 // created to delete it. The task will be safely ignored if the instance is
45 // typedef base::Callback<void (scoped_ptr<Object>)> ErrorCallback;
47 // Object(const ErrorCallback& error_callback)
48 // : self_deleter_helper_(this, error_callback) {
52 // // Post a callback to DoSomethingOnWorkerThread() below to another
56 // void DoSomethingOnWorkerThread() {
58 // if (error_happened)
59 // self_deleter_helper_.MaybeDeleteSoon();
63 // SelfDeleterHelper<MySelfDeletingClass> self_deleter_helper_;
66 // class ObjectOwner {
69 // : object_(new Object(base::Bind(&ObjectOwner::DeleteObjectOnError,
70 // base::Unretained(this))) {
71 // // To keep this example simple base::Unretained(this) is used above but
72 // // note that in a real world scenario the client would have to make sure
73 // // that the ObjectOwner instance is still alive when
74 // // DeleteObjectOnError() gets called below. This can be achieved by
75 // // using a WeakPtr<ObjectOwner> for instance.
79 // object_->StartWork();
83 // void DeleteObjectOnError(scoped_ptr<Object> object) {
84 // DCHECK(thread_checker_.CalledOnValidThread());
85 // DCHECK_EQ(object_, object);
86 // // Do some extra work with |object| before it gets deleted...
88 // ignore_result(object.release());
91 // base::ThreadChecker thread_checker_;
92 // scoped_ptr<Object> object_;
96 class SelfDeleterHelper
{
98 typedef base::Callback
<void (scoped_ptr
<T
>)> DeletionCallback
;
100 SelfDeleterHelper(T
* self_deleting_object
,
101 const DeletionCallback
& deletion_callback
)
102 : construction_runner_(base::MessageLoopProxy::current()),
103 self_deleting_object_(self_deleting_object
),
104 deletion_callback_(deletion_callback
),
105 weak_ptr_factory_(this) {
108 ~SelfDeleterHelper() {
109 DCHECK(construction_runner_
->RunsTasksOnCurrentThread());
112 void MaybeSelfDeleteSoon() {
113 DCHECK(!construction_runner_
->RunsTasksOnCurrentThread());
114 construction_runner_
->PostTask(
116 base::Bind(&SelfDeleterHelper::SelfDelete
,
117 weak_ptr_factory_
.GetWeakPtr()));
122 DCHECK(construction_runner_
->RunsTasksOnCurrentThread());
123 deletion_callback_
.Run(make_scoped_ptr(self_deleting_object_
));
126 const scoped_refptr
<base::SingleThreadTaskRunner
> construction_runner_
;
127 T
* const self_deleting_object_
;
128 const DeletionCallback deletion_callback_
;
130 //WeakPtrFactory's documentation says:
131 // Member variables should appear before the WeakPtrFactory, to ensure
132 // that any WeakPtrs to Controller are invalidated before its members
133 // variable's destructors are executed, rendering them invalid.
134 base::WeakPtrFactory
<SelfDeleterHelper
<T
> > weak_ptr_factory_
;
136 DISALLOW_COPY_AND_ASSIGN(SelfDeleterHelper
);
139 } // namespace forwarder2
141 #endif // TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_