Skip to content

Commit

Permalink
Merge pull request #59 from timou/master
Browse files Browse the repository at this point in the history
Bool is not atomic
  • Loading branch information
darstahl authored Jul 25, 2017
2 parents 3e5ddb0 + 73020a3 commit 7ff8994
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ type atomicBool int32
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
func (b *atomicBool) swap(new bool) bool {
var newInt int32
if new {
newInt = 1
}
return atomic.SwapInt32((*int32)(b), newInt) == 1
}

const (
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
Expand Down Expand Up @@ -71,7 +78,7 @@ func initIo() {
type win32File struct {
handle syscall.Handle
wg sync.WaitGroup
closing bool
closing atomicBool
readDeadline deadlineHandler
writeDeadline deadlineHandler
}
Expand Down Expand Up @@ -107,9 +114,9 @@ func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {

// closeHandle closes the resources associated with a Win32 handle
func (f *win32File) closeHandle() {
if !f.closing {
// Atomically set that we are closing, releasing the resources only once.
if !f.closing.swap(true) {
// cancel all IO and wait for it to complete
f.closing = true
cancelIoEx(f.handle, nil)
f.wg.Wait()
// at this point, no new IO can start
Expand All @@ -127,7 +134,7 @@ func (f *win32File) Close() error {
// prepareIo prepares for a new IO operation.
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
func (f *win32File) prepareIo() (*ioOperation, error) {
if f.closing {
if f.closing.isSet() {
return nil, ErrFileClosed
}
f.wg.Add(1)
Expand Down Expand Up @@ -159,7 +166,7 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
return int(bytes), err
}

if f.closing {
if f.closing.isSet() {
cancelIoEx(f.handle, &c.o)
}

Expand All @@ -175,7 +182,7 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
case r = <-c.ch:
err = r.err
if err == syscall.ERROR_OPERATION_ABORTED {
if f.closing {
if f.closing.isSet() {
err = ErrFileClosed
}
}
Expand Down

0 comments on commit 7ff8994

Please sign in to comment.