1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_CRITICAL_CLOSURE_H_ 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_CRITICAL_CLOSURE_H_ 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/callback.h" 9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/macros.h" 10cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "build/build_config.h" 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_IOS) 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/bind.h" 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/ios/scoped_critical_action.h" 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace internal { 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_IOS) 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Returns true if multi-tasking is supported on this iOS device. 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool IsMultiTaskingSupported(); 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// This class wraps a closure so it can continue to run for a period of time 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// when the application goes to the background by using 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// |ios::ScopedCriticalAction|. 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename R> 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass CriticalClosure { 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat explicit CriticalClosure(const Callback<R(void)>& closure) 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : closure_(closure) {} 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~CriticalClosure() {} 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat R Run() { 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return closure_.Run(); 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private: 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ios::ScopedCriticalAction critical_action_; 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Callback<R(void)> closure_; 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DISALLOW_COPY_AND_ASSIGN(CriticalClosure); 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // defined(OS_IOS) 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace internal 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Returns a closure (which may return a result, but must not require any extra 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// arguments) that will continue to run for a period of time when the 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// application goes to the background if possible on platforms where 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// applications don't execute while backgrounded, otherwise the original task is 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// returned. 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Example: 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// file_task_runner_->PostTask( 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// FROM_HERE, 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// MakeCriticalClosure(base::Bind(&WriteToDiskTask, path_, data))); 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Note new closures might be posted in this closure. If the new closures need 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// background running time, |MakeCriticalClosure| should be applied on them 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// before posting. 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_IOS) 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename R> 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratCallback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) { 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK(internal::IsMultiTaskingSupported()); 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return base::Bind(&internal::CriticalClosure<R>::Run, 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Owned(new internal::CriticalClosure<R>(closure))); 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#else // defined(OS_IOS) 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename R> 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) { 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // No-op for platforms where the application does not need to acquire 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // background time for closures to finish when it goes into the background. 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return closure; 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // defined(OS_IOS) 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_CRITICAL_CLOSURE_H_ 83