github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/cleanup/cleanup.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package cleanup provides utilities to clean "stuff" on defers. 16 package cleanup 17 18 // Cleanup allows defers to be aborted when cleanup needs to happen 19 // conditionally. Usage: 20 // 21 // cu := cleanup.Make(func() { f.Close() }) 22 // defer cu.Clean() // failure before release is called will close the file. 23 // ... 24 // cu.Add(func() { f2.Close() }) // Adds another cleanup function 25 // ... 26 // cu.Release() // on success, aborts closing the file. 27 // return f 28 type Cleanup struct { 29 cleaners []func() 30 } 31 32 // Make creates a new Cleanup object. 33 func Make(f func()) Cleanup { 34 return Cleanup{cleaners: []func(){f}} 35 } 36 37 // Add adds a new function to be called on Clean(). 38 func (c *Cleanup) Add(f func()) { 39 c.cleaners = append(c.cleaners, f) 40 } 41 42 // Clean calls all cleanup functions in reverse order. 43 func (c *Cleanup) Clean() { 44 clean(c.cleaners) 45 c.cleaners = nil 46 } 47 48 // Release releases the cleanup from its duties, i.e. cleanup functions are not 49 // called after this point. Returns a function that calls all registered 50 // functions in case the caller has use for them. 51 func (c *Cleanup) Release() func() { 52 old := c.cleaners 53 c.cleaners = nil 54 return func() { clean(old) } 55 } 56 57 func clean(cleaners []func()) { 58 for i := len(cleaners) - 1; i >= 0; i-- { 59 cleaners[i]() 60 } 61 }