1 // Copyright 2014 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 CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_HELPER_H_
6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_HELPER_H_
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/sequenced_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
14 // TODO(tzik): Merge this file to media/base/bind_to_current_loop.h.
16 namespace sync_file_system
{
17 namespace drive_backend
{
22 typename
base::enable_if
<
23 base::internal::IsMoveOnlyType
<T
>::value
,
24 base::internal::PassedWrapper
<T
> >::type
26 return base::Passed(&t
);
30 typename
base::enable_if
<
31 !base::internal::IsMoveOnlyType
<T
>::value
,
38 class CallbackHolder
{
40 CallbackHolder(const scoped_refptr
<base::SequencedTaskRunner
>& task_runner
,
41 const tracked_objects::Location
& from_here
,
42 const base::Callback
<T
>& callback
)
43 : task_runner_(task_runner
),
44 from_here_(from_here
),
45 callback_(new base::Callback
<T
>(callback
)) {
46 DCHECK(task_runner_
.get());
50 base::Callback
<T
>* callback
= callback_
.release();
51 if (!task_runner_
->DeleteSoon(from_here_
, callback
))
55 base::SequencedTaskRunner
* task_runner() const { return task_runner_
.get(); }
56 const tracked_objects::Location
& from_here() const { return from_here_
; }
57 const base::Callback
<T
>& callback() const { return *callback_
; }
60 scoped_refptr
<base::SequencedTaskRunner
> task_runner_
;
61 const tracked_objects::Location from_here_
;
62 scoped_ptr
<base::Callback
<T
> > callback_
;
64 DISALLOW_COPY_AND_ASSIGN(CallbackHolder
);
68 struct RelayToTaskRunnerHelper
;
70 template <typename
... Args
>
71 struct RelayToTaskRunnerHelper
<void(Args
...)> {
72 static void Run(CallbackHolder
<void(Args
...)>* holder
, Args
... args
) {
73 holder
->task_runner()->PostTask(
75 base::Bind(holder
->callback(),
76 RebindForward(args
)...));
80 } // namespace internal
83 base::Callback
<T
> RelayCallbackToTaskRunner(
84 const scoped_refptr
<base::SequencedTaskRunner
>& task_runner
,
85 const tracked_objects::Location
& from_here
,
86 const base::Callback
<T
>& callback
) {
87 DCHECK(task_runner
->RunsTasksOnCurrentThread());
89 if (callback
.is_null())
90 return base::Callback
<T
>();
92 return base::Bind(&internal::RelayToTaskRunnerHelper
<T
>::Run
,
93 base::Owned(new internal::CallbackHolder
<T
>(
94 task_runner
, from_here
, callback
)));
98 base::Callback
<T
> RelayCallbackToCurrentThread(
99 const tracked_objects::Location
& from_here
,
100 const base::Callback
<T
>& callback
) {
101 return RelayCallbackToTaskRunner(
102 base::ThreadTaskRunnerHandle::Get(),
103 from_here
, callback
);
106 } // namespace drive_backend
107 } // namespace sync_file_system
109 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_HELPER_H_