Home | History | Annotate | Download | only in base
      1 // 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"
      9 
     10 #if defined(OS_IOS)
     11 #include "base/bind.h"
     12 #include "base/ios/scoped_critical_action.h"
     13 #endif
     14 
     15 namespace base {
     16 
     17 namespace internal {
     18 
     19 #if defined(OS_IOS)
     20 // Returns true if multi-tasking is supported on this iOS device.
     21 bool IsMultiTaskingSupported();
     22 
     23 // This class wraps a closure so it can continue to run for a period of time
     24 // when the application goes to the background by using
     25 // |ios::ScopedCriticalAction|.
     26 template <typename R>
     27 class CriticalClosure {
     28  public:
     29   explicit CriticalClosure(const Callback<R(void)>& closure)
     30       : closure_(closure) {}
     31 
     32   ~CriticalClosure() {}
     33 
     34   R Run() {
     35     return closure_.Run();
     36   }
     37 
     38  private:
     39   ios::ScopedCriticalAction critical_action_;
     40   Callback<R(void)> closure_;
     41 
     42   DISALLOW_COPY_AND_ASSIGN(CriticalClosure);
     43 };
     44 #endif  // defined(OS_IOS)
     45 
     46 }  // namespace internal
     47 
     48 // Returns a closure (which may return a result, but must not require any extra
     49 // arguments) that will continue to run for a period of time when the
     50 // application goes to the background if possible on platforms where
     51 // applications don't execute while backgrounded, otherwise the original task is
     52 // returned.
     53 //
     54 // Example:
     55 //   file_message_loop_proxy_->PostTask(
     56 //       FROM_HERE,
     57 //       MakeCriticalClosure(base::Bind(&WriteToDiskTask, path_, data)));
     58 //
     59 // Note new closures might be posted in this closure. If the new closures need
     60 // background running time, |MakeCriticalClosure| should be applied on them
     61 // before posting.
     62 #if defined(OS_IOS)
     63 template <typename R>
     64 Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) {
     65   DCHECK(internal::IsMultiTaskingSupported());
     66   return base::Bind(&internal::CriticalClosure<R>::Run,
     67                     Owned(new internal::CriticalClosure<R>(closure)));
     68 }
     69 #else  // defined(OS_IOS)
     70 template <typename R>
     71 inline Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) {
     72   // No-op for platforms where the application does not need to acquire
     73   // background time for closures to finish when it goes into the background.
     74   return closure;
     75 }
     76 #endif  // defined(OS_IOS)
     77 
     78 }  // namespace base
     79 
     80 #endif  // BASE_CRITICAL_CLOSURE_H_
     81