Description
The stopOCSPCacheClearing channel is defined as a buffered channel with capacity 2:
https://github.com/snowflakedb/gosnowflake/blob/master/ocsp.go#L109
var stopOCSPCacheClearing = make(chan struct{}, 2)
This causes a race condition in the stop() method:
func (occ *ocspCacheClearerType) stop() {
occ.mu.Lock()
running := occ.running
occ.mu.Unlock()
if running {
stopOCSPCacheClearing <- struct{}{} // Non-blocking, goes into buffer
<-stopOCSPCacheClearing // Could immediately read its own value!
}
}
Problem
With a buffered channel:
- The send in
stop() puts a value into the buffer (non-blocking since buffer has space)
- The receive in
stop() could immediately read that same value back
stop() returns without the goroutine ever seeing the stop signal
The goroutine continues running, and the synchronization handshake is broken.
Expected Behavior
The stop() function should block until the cache clearer goroutine has actually stopped.
Suggested Fix
Change the channel to be unbuffered:
var stopOCSPCacheClearing = make(chan struct{})
With an unbuffered channel:
- The send in
stop() blocks until the goroutine receives
- The goroutine's acknowledgment send blocks until
stop() receives
This ensures proper synchronization for the handshake pattern.
Impact
This bug can cause:
- Goroutine leaks when
StopOCSPCacheClearer() is called
- Resources (ticker) not being released
- Non-deterministic behavior in tests
Description
The
stopOCSPCacheClearingchannel is defined as a buffered channel with capacity 2:https://github.com/snowflakedb/gosnowflake/blob/master/ocsp.go#L109
This causes a race condition in the
stop()method:Problem
With a buffered channel:
stop()puts a value into the buffer (non-blocking since buffer has space)stop()could immediately read that same value backstop()returns without the goroutine ever seeing the stop signalThe goroutine continues running, and the synchronization handshake is broken.
Expected Behavior
The
stop()function should block until the cache clearer goroutine has actually stopped.Suggested Fix
Change the channel to be unbuffered:
With an unbuffered channel:
stop()blocks until the goroutine receivesstop()receivesThis ensures proper synchronization for the handshake pattern.
Impact
This bug can cause:
StopOCSPCacheClearer()is called