Skip to content

Instantly share code, notes, and snippets.

@sykesm
Created December 9, 2014 20:22
Show Gist options
  • Save sykesm/464b30b1cc87aaf4aec6 to your computer and use it in GitHub Desktop.
Save sykesm/464b30b1cc87aaf4aec6 to your computer and use it in GitHub Desktop.
Race on asynch close
package main
import (
"bytes"
"errors"
"io"
"io/ioutil"
"os"
)
func CancellableCopy(r io.ReadCloser, w io.Writer, cancelChan chan struct{}) error {
defer r.Close()
completeChan := make(chan error)
go func() {
_, err := io.Copy(w, r)
completeChan <- err
}()
select {
case err := <-completeChan:
return err
case <-cancelChan:
return errors.New("canceled")
}
}
func main() {
filename := createTmpFile()
file, err := os.Open(filename)
panicOnError(err)
defer os.Remove(file.Name())
writer := new(bytes.Buffer)
cancel := make(chan struct{})
close(cancel)
err = CancellableCopy(file, writer, cancel)
}
func createTmpFile() string {
tmpFile, err := ioutil.TempFile("", "some-tmp-file")
panicOnError(err)
_, err = tmpFile.WriteString("this is a line of text\n")
panicOnError(err)
err = tmpFile.Close()
panicOnError(err)
return tmpFile.Name()
}
func panicOnError(err error) {
if err != nil {
panic(err.Error())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment