Skip to content

proposal: io: add OnceCloser helper #25408

Open
@bradfitz

Description

@bradfitz

Proposal, to add to the io package:

// OnceCloser returns a Closer wrapping c that guarantees it only calls c.Close
// once and is safe for use by multiple goroutines. Each call to the returned Closer
// will return the same value, as returned by c.Close.
func OnceCloser(c Closer) Closer {
	return &onceCloser{c: c}
}

With implementation like:

type onceCloser struct {
	c    Closer
	once sync.Once
	err  error
}

func (c *onceCloser) Close() error {
	c.once.Do(c.close)
	return c.err
}

func (c *onceCloser) close() { c.err = c.c.Close() }

This would let people safely write code like:

       oc := io.OnceCloser(file)
       defer oc.Close()

       ....
       if err != nil {
             return nil, err
       }
       if err := oc.Close(); err != nil {
             return nil, err
      }

... without worrying about double calls to file.Close, which is undefined since https://golang.org/cl/8575043

https://golang.org/pkg/io/#Closer

// The behavior of Close after the first call is undefined.
// Specific implementations may document their own behavior.

/cc @bcmills @mpvl @ianlancetaylor

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions