61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
|
// Copyright 2020 The gVisor Authors.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
// Package cleanup provides utilities to clean "stuff" on defers.
|
||
|
package cleanup
|
||
|
|
||
|
// Cleanup allows defers to be aborted when cleanup needs to happen
|
||
|
// conditionally. Usage:
|
||
|
// cu := cleanup.Make(func() { f.Close() })
|
||
|
// defer cu.Clean() // failure before release is called will close the file.
|
||
|
// ...
|
||
|
// cu.Add(func() { f2.Close() }) // Adds another cleanup function
|
||
|
// ...
|
||
|
// cu.Release() // on success, aborts closing the file.
|
||
|
// return f
|
||
|
type Cleanup struct {
|
||
|
cleaners []func()
|
||
|
}
|
||
|
|
||
|
// Make creates a new Cleanup object.
|
||
|
func Make(f func()) Cleanup {
|
||
|
return Cleanup{cleaners: []func(){f}}
|
||
|
}
|
||
|
|
||
|
// Add adds a new function to be called on Clean().
|
||
|
func (c *Cleanup) Add(f func()) {
|
||
|
c.cleaners = append(c.cleaners, f)
|
||
|
}
|
||
|
|
||
|
// Clean calls all cleanup functions in reverse order.
|
||
|
func (c *Cleanup) Clean() {
|
||
|
clean(c.cleaners)
|
||
|
c.cleaners = nil
|
||
|
}
|
||
|
|
||
|
// Release releases the cleanup from its duties, i.e. cleanup functions are not
|
||
|
// called after this point. Returns a function that calls all registered
|
||
|
// functions in case the caller has use for them.
|
||
|
func (c *Cleanup) Release() func() {
|
||
|
old := c.cleaners
|
||
|
c.cleaners = nil
|
||
|
return func() { clean(old) }
|
||
|
}
|
||
|
|
||
|
func clean(cleaners []func()) {
|
||
|
for i := len(cleaners) - 1; i >= 0; i-- {
|
||
|
cleaners[i]()
|
||
|
}
|
||
|
}
|