blob: 6ebd7afa503ce66d6b12c36fe5bfb9d1dbb80103 [file] [log] [blame]
Daniel Eratb8cf9492015-07-06 13:18:13 -06001// 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"
Alex Vakulenkocce46a02016-01-15 13:02:14 -08009#include "base/macros.h"
10#include "build/build_config.h"
Daniel Eratb8cf9492015-07-06 13:18:13 -060011
12#if defined(OS_IOS)
13#include "base/bind.h"
14#include "base/ios/scoped_critical_action.h"
15#endif
16
17namespace base {
18
19namespace 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
52// 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:
57// file_task_runner_->PostTask(
58// 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)
65template <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) {
74 // 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}
78#endif // defined(OS_IOS)
79
80} // namespace base
81
82#endif // BASE_CRITICAL_CLOSURE_H_