d96903d5db0677e65e069731cfe4a7e825914afc
[platform/framework/web/crosswalk.git] / src / tools / android / forwarder2 / self_deleter_helper.h
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
5 #ifndef TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
6 #define TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
7
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/message_loop/message_loop_proxy.h"
17
18 namespace base {
19
20 class SingleThreadTaskRunner;
21
22 }  // namespace base
23
24 namespace forwarder2 {
25
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.
31 //
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.
37 //
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.
41 //
42 // Usage example:
43 // class Object {
44 //  public:
45 //   typedef base::Callback<void (scoped_ptr<Object>)> ErrorCallback;
46 //
47 //   Object(const ErrorCallback& error_callback)
48 //       : self_deleter_helper_(this, error_callback) {
49 //   }
50 //
51 //   void StartWork() {
52 //     // Post a callback to DoSomethingOnWorkerThread() below to another
53 //     // thread.
54 //   }
55 //
56 //   void DoSomethingOnWorkerThread() {
57 //     ...
58 //     if (error_happened)
59 //       self_deleter_helper_.MaybeDeleteSoon();
60 //   }
61 //
62 //  private:
63 //   SelfDeleterHelper<MySelfDeletingClass> self_deleter_helper_;
64 // };
65 //
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 //   }
77 //
78 //   void StartWork() {
79 //     object_->StartWork();
80 //   }
81 //
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 //   }
90 //
91 //   base::ThreadChecker thread_checker_;
92 //   scoped_ptr<Object> object_;
93 // };
94 //
95 template <typename T>
96 class SelfDeleterHelper {
97  public:
98   typedef base::Callback<void (scoped_ptr<T>)> DeletionCallback;
99
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) {
106   }
107
108   ~SelfDeleterHelper() {
109     DCHECK(construction_runner_->RunsTasksOnCurrentThread());
110   }
111
112   void MaybeSelfDeleteSoon() {
113     DCHECK(!construction_runner_->RunsTasksOnCurrentThread());
114     construction_runner_->PostTask(
115         FROM_HERE,
116         base::Bind(&SelfDeleterHelper::SelfDelete,
117                    weak_ptr_factory_.GetWeakPtr()));
118   }
119
120  private:
121   void SelfDelete() {
122     DCHECK(construction_runner_->RunsTasksOnCurrentThread());
123     deletion_callback_.Run(make_scoped_ptr(self_deleting_object_));
124   }
125
126   const scoped_refptr<base::SingleThreadTaskRunner> construction_runner_;
127   T* const self_deleting_object_;
128   const DeletionCallback deletion_callback_;
129
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_;
135
136   DISALLOW_COPY_AND_ASSIGN(SelfDeleterHelper);
137 };
138
139 }  // namespace forwarder2
140
141 #endif  // TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_