github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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 // cu := cleanup.Make(func() { f.Close() }) 21 // defer cu.Clean() // failure before release is called will close the file. 22 // ... 23 // cu.Add(func() { f2.Close() }) // Adds another cleanup function 24 // ... 25 // cu.Release() // on success, aborts closing the file. 26 // return f 27 type Cleanup struct { 28 cleaners []func() 29 } 30 31 // Make creates a new Cleanup object. 32 func Make(f func()) Cleanup { 33 return Cleanup{cleaners: []func(){f}} 34 } 35 36 // Add adds a new function to be called on Clean(). 37 func (c *Cleanup) Add(f func()) { 38 c.cleaners = append(c.cleaners, f) 39 } 40 41 // Clean calls all cleanup functions in reverse order. 42 func (c *Cleanup) Clean() { 43 clean(c.cleaners) 44 c.cleaners = nil 45 } 46 47 // Release releases the cleanup from its duties, i.e. cleanup functions are not 48 // called after this point. Returns a function that calls all registered 49 // functions in case the caller has use for them. 50 func (c *Cleanup) Release() func() { 51 old := c.cleaners 52 c.cleaners = nil 53 return func() { clean(old) } 54 } 55 56 func clean(cleaners []func()) { 57 for i := len(cleaners) - 1; i >= 0; i-- { 58 cleaners[i]() 59 } 60 }