Unify Help/Feedback/Credits menus.
[chromium-blink-merge.git] / tools / android / forwarder2 / self_deleter_helper.h
blob866960f3d58b0ce45fb8feeb2116d244f62e12b1
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"
9 #include "base/bind.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/thread_task_runner_handle.h"
18 namespace base {
20 class SingleThreadTaskRunner;
22 } // namespace base
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
28 // or worker thread.
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
40 // otherwise deleted.
42 // Usage example:
43 // class Object {
44 // public:
45 // typedef base::Callback<void (scoped_ptr<Object>)> ErrorCallback;
47 // Object(const ErrorCallback& error_callback)
48 // : self_deleter_helper_(this, error_callback) {
49 // }
51 // void StartWork() {
52 // // Post a callback to DoSomethingOnWorkerThread() below to another
53 // // thread.
54 // }
56 // void DoSomethingOnWorkerThread() {
57 // ...
58 // if (error_happened)
59 // self_deleter_helper_.MaybeDeleteSoon();
60 // }
62 // private:
63 // SelfDeleterHelper<MySelfDeletingClass> self_deleter_helper_;
64 // };
66 // class ObjectOwner {
67 // public:
68 // 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.
76 // }
78 // void StartWork() {
79 // object_->StartWork();
80 // }
82 // private:
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...
87 // object_.reset();
88 // ignore_result(object.release());
89 // }
91 // base::ThreadChecker thread_checker_;
92 // scoped_ptr<Object> object_;
93 // };
95 template <typename T>
96 class SelfDeleterHelper {
97 public:
98 typedef base::Callback<void (scoped_ptr<T>)> DeletionCallback;
100 SelfDeleterHelper(T* self_deleting_object,
101 const DeletionCallback& deletion_callback)
102 : construction_runner_(base::ThreadTaskRunnerHandle::Get()),
103 self_deleting_object_(self_deleting_object),
104 deletion_callback_(deletion_callback),
105 weak_ptr_factory_(this) {}
107 ~SelfDeleterHelper() {
108 DCHECK(construction_runner_->RunsTasksOnCurrentThread());
111 void MaybeSelfDeleteSoon() {
112 DCHECK(!construction_runner_->RunsTasksOnCurrentThread());
113 construction_runner_->PostTask(
114 FROM_HERE,
115 base::Bind(&SelfDeleterHelper::SelfDelete,
116 weak_ptr_factory_.GetWeakPtr()));
119 private:
120 void SelfDelete() {
121 DCHECK(construction_runner_->RunsTasksOnCurrentThread());
122 deletion_callback_.Run(make_scoped_ptr(self_deleting_object_));
125 const scoped_refptr<base::SingleThreadTaskRunner> construction_runner_;
126 T* const self_deleting_object_;
127 const DeletionCallback deletion_callback_;
129 //WeakPtrFactory's documentation says:
130 // Member variables should appear before the WeakPtrFactory, to ensure
131 // that any WeakPtrs to Controller are invalidated before its members
132 // variable's destructors are executed, rendering them invalid.
133 base::WeakPtrFactory<SelfDeleterHelper<T> > weak_ptr_factory_;
135 DISALLOW_COPY_AND_ASSIGN(SelfDeleterHelper);
138 } // namespace forwarder2
140 #endif // TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_