• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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