blob: 6ebd7afa503ce66d6b12c36fe5bfb9d1dbb80103 [file] [log] [blame]
chenyu@chromium.org4c63e782012-08-02 00:42:16 +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
5#ifndef BASE_CRITICAL_CLOSURE_H_
6#define BASE_CRITICAL_CLOSURE_H_
7
8#include "base/callback.h"
avia6a6a682015-12-27 07:15:14 +09009#include "base/macros.h"
10#include "build/build_config.h"
chenyu@chromium.org4c63e782012-08-02 00:42:16 +090011
gab@chromium.orga06c8a52014-05-09 20:57:31 +090012#if defined(OS_IOS)
13#include "base/bind.h"
14#include "base/ios/scoped_critical_action.h"
15#endif
16
chenyu@chromium.org4c63e782012-08-02 00:42:16 +090017namespace base {
18
gab@chromium.orga06c8a52014-05-09 20:57:31 +090019namespace internal {
20
21#if defined(OS_IOS)
22// Returns true if multi-tasking is supported on this iOS device.
23bool IsMultiTaskingSupported();
24
25// This class wraps a closure so it can continue to run for a period of time
26// when the application goes to the background by using
27// |ios::ScopedCriticalAction|.
28template <typename R>
29class CriticalClosure {
30 public:
31 explicit CriticalClosure(const Callback<R(void)>& closure)
32 : closure_(closure) {}
33
34 ~CriticalClosure() {}
35
36 R Run() {
37 return closure_.Run();
38 }
39
40 private:
41 ios::ScopedCriticalAction critical_action_;
42 Callback<R(void)> closure_;
43
44 DISALLOW_COPY_AND_ASSIGN(CriticalClosure);
45};
46#endif // defined(OS_IOS)
47
48} // namespace internal
49
50// Returns a closure (which may return a result, but must not require any extra
51// arguments) that will continue to run for a period of time when the
chenyu@chromium.org4c63e782012-08-02 00:42:16 +090052// application goes to the background if possible on platforms where
53// applications don't execute while backgrounded, otherwise the original task is
54// returned.
55//
56// Example:
skyostil97aefe12015-05-01 04:06:15 +090057// file_task_runner_->PostTask(
chenyu@chromium.org4c63e782012-08-02 00:42:16 +090058// FROM_HERE,
59// MakeCriticalClosure(base::Bind(&WriteToDiskTask, path_, data)));
60//
61// Note new closures might be posted in this closure. If the new closures need
62// background running time, |MakeCriticalClosure| should be applied on them
63// before posting.
64#if defined(OS_IOS)
gab@chromium.orga06c8a52014-05-09 20:57:31 +090065template <typename R>
66Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) {
67 DCHECK(internal::IsMultiTaskingSupported());
68 return base::Bind(&internal::CriticalClosure<R>::Run,
69 Owned(new internal::CriticalClosure<R>(closure)));
70}
71#else // defined(OS_IOS)
72template <typename R>
73inline Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) {
chenyu@chromium.org4c63e782012-08-02 00:42:16 +090074 // No-op for platforms where the application does not need to acquire
75 // background time for closures to finish when it goes into the background.
76 return closure;
77}
gab@chromium.orga06c8a52014-05-09 20:57:31 +090078#endif // defined(OS_IOS)
chenyu@chromium.org4c63e782012-08-02 00:42:16 +090079
80} // namespace base
81
82#endif // BASE_CRITICAL_CLOSURE_H_