Skip to content

Commit

Permalink
Prevent adding to a sync.WaitGroup that has a waiter
Browse files Browse the repository at this point in the history
Signed-off-by: Darren Stahl <[email protected]>
  • Loading branch information
darstahl committed Aug 3, 2017
1 parent 036d9d8 commit c57b87d
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func initIo() {
type win32File struct {
handle syscall.Handle
wg sync.WaitGroup
wgLock sync.RWMutex
closing atomicBool
readDeadline deadlineHandler
writeDeadline deadlineHandler
Expand Down Expand Up @@ -118,7 +119,9 @@ func (f *win32File) closeHandle() {
if !f.closing.swap(true) {
// cancel all IO and wait for it to complete
cancelIoEx(f.handle, nil)
f.wgLock.Lock()
f.wg.Wait()
f.wgLock.Unlock()
// at this point, no new IO can start
syscall.Close(f.handle)
f.handle = 0
Expand All @@ -134,10 +137,13 @@ 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) {
f.wgLock.RLock()
if f.closing.isSet() {
f.wgLock.RUnlock()
return nil, ErrFileClosed
}
f.wg.Add(1)
f.wgLock.RUnlock()
c := &ioOperation{}
c.ch = make(chan ioResult)
return c, nil
Expand Down

0 comments on commit c57b87d

Please sign in to comment.