1 // Copyright 2013 The Flutter 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 FLUTTER_FML_CLOSURE_H_ 6 #define FLUTTER_FML_CLOSURE_H_ 7 8 #include <functional> 9 10 #include "flutter/fml/macros.h" 11 12 namespace fml { 13 14 using closure = std::function<void()>; 15 16 //------------------------------------------------------------------------------ 17 /// @brief Wraps a closure that is invoked in the destructor unless 18 /// released by the caller. 19 /// 20 /// This is especially useful in dealing with APIs that return a 21 /// resource by accepting ownership of a sub-resource and a closure 22 /// that releases that resource. When such APIs are chained, each 23 /// link in the chain must check that the next member in the chain 24 /// has accepted the resource. If not, it must invoke the closure 25 /// eagerly. Not doing this results in a resource leak in the 26 /// erroneous case. Using this wrapper, the closure can be released 27 /// once the next call in the chain has successfully accepted 28 /// ownership of the resource. If not, the closure gets invoked 29 /// automatically at the end of the scope. This covers the cases 30 /// where there are early returns as well. 31 /// 32 class ScopedCleanupClosure { 33 public: ScopedCleanupClosure(fml::closure closure)34 ScopedCleanupClosure(fml::closure closure) : closure_(closure) {} 35 ~ScopedCleanupClosure()36 ~ScopedCleanupClosure() { 37 if (closure_) { 38 closure_(); 39 } 40 } 41 Release()42 fml::closure Release() { 43 fml::closure closure = closure_; 44 closure_ = nullptr; 45 return closure; 46 } 47 48 private: 49 fml::closure closure_; 50 51 FML_DISALLOW_COPY_AND_ASSIGN(ScopedCleanupClosure); 52 }; 53 54 } // namespace fml 55 56 #endif // FLUTTER_FML_CLOSURE_H_ 57