Skip to content

Commit cd510b3

Browse files
committed
fix race condition where "CloseAndZero" is executed while still used
1 parent 39d8332 commit cd510b3

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

udp/udp_rio_windows.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"sync"
1515
"sync/atomic"
1616
"syscall"
17+
"time"
1718
"unsafe"
1819

1920
"github.com/sirupsen/logrus"
@@ -178,10 +179,11 @@ func (u *RIOConn) receive(buf []byte) (int, windows.RawSockaddrInet6, error) {
178179
retry:
179180
count = 0
180181
for tries := 0; count == 0 && tries < receiveSpins; tries++ {
182+
if !u.isOpen.Load() { // might have changed since first check before the mutex lock
183+
return 0, windows.RawSockaddrInet6{}, net.ErrClosed
184+
}
185+
181186
if tries > 0 {
182-
if !u.isOpen.Load() {
183-
return 0, windows.RawSockaddrInet6{}, net.ErrClosed
184-
}
185187
procyield(1)
186188
}
187189

@@ -247,6 +249,10 @@ func (u *RIOConn) WriteTo(buf []byte, ip netip.AddrPort) error {
247249
u.tx.mu.Lock()
248250
defer u.tx.mu.Unlock()
249251

252+
if !u.isOpen.Load() { // might have changed since first check before the mutex lock
253+
return net.ErrClosed
254+
}
255+
250256
count := winrio.DequeueCompletion(u.tx.cq, u.results[:])
251257
if count == 0 && u.tx.isFull {
252258
err := winrio.Notify(u.tx.cq)
@@ -323,6 +329,14 @@ func (u *RIOConn) Close() error {
323329
windows.PostQueuedCompletionStatus(u.rx.iocp, 0, 0, nil)
324330
windows.PostQueuedCompletionStatus(u.tx.iocp, 0, 0, nil)
325331

332+
u.rx.mu.Lock() // for waiting till active reader is done
333+
time.Sleep(time.Millisecond * 0) // avoid warning about empty critical section
334+
u.rx.mu.Unlock()
335+
336+
u.tx.mu.Lock() // for waiting till active writer is done
337+
time.Sleep(time.Millisecond * 0) // avoid warning about empty critical section
338+
u.tx.mu.Unlock()
339+
326340
u.rx.CloseAndZero()
327341
u.tx.CloseAndZero()
328342
if u.sock != 0 {

0 commit comments

Comments
 (0)