Skip to content

Commit b686f7c

Browse files
GODRIVER-2810 Guard rttMonitor connection
1 parent 20d1b17 commit b686f7c

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
2828
tzdata \
2929
gpg \
3030
apt-utils \
31+
libc6-dev \
32+
gcc \
3133
make && \
3234
apt-add-repository ppa:longsleep/golang-backports && \
3335
apt-get -qq update && \

x/mongo/driver/topology/rtt_monitor.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ type rttConfig struct {
3939
}
4040

4141
type rttMonitor struct {
42-
mu sync.RWMutex // mu guards samples, offset, minRTT, averageRTT, and averageRTTSet
42+
mu sync.RWMutex // mu guards samples, offset, minRTT, averageRTT, and averageRTTSet
43+
44+
// connMu guards connecting and disconnecting. This is necessary since
45+
// disconnecting will await the cancelation of a started connection. The
46+
// use case for rttMonitor.connect needs to be goroutine safe.
47+
connMu sync.Mutex
4348
samples []time.Duration
4449
offset int
4550
minRTT time.Duration
@@ -52,6 +57,7 @@ type rttMonitor struct {
5257
ctx context.Context
5358
cancelFn context.CancelFunc
5459
started bool
60+
done chan struct{}
5561
}
5662

5763
var _ driver.RTTMonitor = &rttMonitor{}
@@ -75,20 +81,34 @@ func newRTTMonitor(cfg *rttConfig) *rttMonitor {
7581
}
7682

7783
func (r *rttMonitor) connect() {
78-
r.closeWg.Add(1)
84+
r.connMu.Lock()
85+
defer r.connMu.Unlock()
86+
7987
r.started = true
80-
go r.start()
88+
r.closeWg.Add(1)
89+
90+
go func() {
91+
defer r.closeWg.Done()
92+
93+
r.start()
94+
}()
8195
}
8296

8397
func (r *rttMonitor) disconnect() {
84-
// Signal for the routine to stop.
98+
r.connMu.Lock()
99+
defer r.connMu.Unlock()
100+
101+
if !r.started {
102+
return
103+
}
104+
85105
r.cancelFn()
106+
107+
// Wait for the existing connection to complete.
86108
r.closeWg.Wait()
87109
}
88110

89111
func (r *rttMonitor) start() {
90-
defer r.closeWg.Done()
91-
92112
var conn *connection
93113
defer func() {
94114
if conn != nil {

0 commit comments

Comments
 (0)