blob: 325555ed6334d28400903e8658e8d3645a7c3cf0 [file] [log] [blame]
akalin@chromium.org062f9682012-02-15 10:43:19 +09001// Copyright (c) 2012 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
dbeam@chromium.org36f60402013-05-08 14:35:24 +09005#ifndef BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_
6#define BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_
akalin@chromium.org062f9682012-02-15 10:43:19 +09007
8#include "base/basictypes.h"
tzik6d9f3622014-09-03 19:06:34 +09009#include "base/debug/alias.h"
akalin@chromium.org062f9682012-02-15 10:43:19 +090010
11// TODO(akalin): Investigate whether it's possible to just have
12// SequencedTaskRunner use these helpers (instead of MessageLoop).
13// Then we can just move these to sequenced_task_runner.h.
14
15namespace tracked_objects {
16class Location;
17}
18
19namespace base {
20
21namespace subtle {
22template <class T, class R> class DeleteHelperInternal;
23template <class T, class R> class ReleaseHelperInternal;
24}
25
26// Template helpers which use function indirection to erase T from the
27// function signature while still remembering it so we can call the
28// correct destructor/release function.
29//
30// We use this trick so we don't need to include bind.h in a header
31// file like sequenced_task_runner.h. We also wrap the helpers in a
32// templated class to make it easier for users of DeleteSoon to
33// declare the helper as a friend.
34template <class T>
35class DeleteHelper {
36 private:
37 template <class T2, class R> friend class subtle::DeleteHelperInternal;
38
39 static void DoDelete(const void* object) {
tzik6d9f3622014-09-03 19:06:34 +090040 // TODO(tzik): Remove this after http://crbug.com/393634 is fixed.
41 const char* function_name = __FUNCTION__;
42 debug::Alias(&function_name);
43
akalin@chromium.org062f9682012-02-15 10:43:19 +090044 delete reinterpret_cast<const T*>(object);
45 }
46
47 DISALLOW_COPY_AND_ASSIGN(DeleteHelper);
48};
49
50template <class T>
51class ReleaseHelper {
52 private:
53 template <class T2, class R> friend class subtle::ReleaseHelperInternal;
54
55 static void DoRelease(const void* object) {
56 reinterpret_cast<const T*>(object)->Release();
57 }
58
59 DISALLOW_COPY_AND_ASSIGN(ReleaseHelper);
60};
61
62namespace subtle {
63
64// An internal SequencedTaskRunner-like class helper for DeleteHelper
65// and ReleaseHelper. We don't want to expose the Do*() functions
66// directly directly since the void* argument makes it possible to
67// pass/ an object of the wrong type to delete. Instead, we force
68// callers to go through these internal helpers for type
69// safety. SequencedTaskRunner-like classes which expose DeleteSoon or
70// ReleaseSoon methods should friend the appropriate helper and
71// implement a corresponding *Internal method with the following
72// signature:
73//
74// bool(const tracked_objects::Location&,
75// void(*function)(const void*),
76// void* object)
77//
78// An implementation of this function should simply create a
79// base::Closure from (function, object) and return the result of
80// posting the task.
81template <class T, class ReturnType>
82class DeleteHelperInternal {
83 public:
84 template <class SequencedTaskRunnerType>
85 static ReturnType DeleteViaSequencedTaskRunner(
86 SequencedTaskRunnerType* sequenced_task_runner,
87 const tracked_objects::Location& from_here,
88 const T* object) {
89 return sequenced_task_runner->DeleteSoonInternal(
90 from_here, &DeleteHelper<T>::DoDelete, object);
91 }
92
93 private:
94 DISALLOW_COPY_AND_ASSIGN(DeleteHelperInternal);
95};
96
97template <class T, class ReturnType>
98class ReleaseHelperInternal {
99 public:
100 template <class SequencedTaskRunnerType>
101 static ReturnType ReleaseViaSequencedTaskRunner(
102 SequencedTaskRunnerType* sequenced_task_runner,
103 const tracked_objects::Location& from_here,
104 const T* object) {
105 return sequenced_task_runner->ReleaseSoonInternal(
106 from_here, &ReleaseHelper<T>::DoRelease, object);
107 }
108
109 private:
110 DISALLOW_COPY_AND_ASSIGN(ReleaseHelperInternal);
111};
112
113} // namespace subtle
114
115} // namespace base
116
dbeam@chromium.org36f60402013-05-08 14:35:24 +0900117#endif // BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_