@@ -95,12 +95,11 @@ type sshSmartSubtransport struct {
95
95
}
96
96
97
97
type connection struct {
98
- conn net.Conn
99
98
client * ssh.Client
100
99
session * ssh.Session
101
100
currentStream * sshSmartSubtransportStream
102
101
connected bool
103
- m sync.Mutex
102
+ m sync.RWMutex
104
103
}
105
104
106
105
func (t * sshSmartSubtransport ) Action (transportOptionsURL string , action git2go.SmartServiceAction ) (git2go.SmartSubtransportStream , error ) {
@@ -155,11 +154,6 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
155
154
return nil , fmt .Errorf ("unexpected action: %v" , action )
156
155
}
157
156
158
- if t .con .connected {
159
- // Disregard errors from previous stream, futher details inside Close().
160
- _ = t .Close ()
161
- }
162
-
163
157
port := "22"
164
158
if u .Port () != "" {
165
159
port = u .Port ()
@@ -189,13 +183,18 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
189
183
return nil
190
184
}
191
185
186
+ t .con .m .RLock ()
187
+ if t .con .connected == true {
188
+ // The connection is no longer shared across actions, so ensures
189
+ // all has been released before starting a new connection.
190
+ _ = t .Close ()
191
+ }
192
+ t .con .m .RUnlock ()
193
+
192
194
err = t .createConn (t .addr , sshConfig )
193
195
if err != nil {
194
196
return nil , err
195
197
}
196
- t .con .m .Lock ()
197
- t .con .connected = true
198
- t .con .m .Unlock ()
199
198
200
199
traceLog .Info ("[ssh]: creating new ssh session" )
201
200
if t .con .session , err = t .con .client .NewSession (); err != nil {
@@ -244,12 +243,12 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
244
243
return nil
245
244
246
245
default :
247
- t .con .m .Lock ()
246
+ t .con .m .RLock ()
248
247
if ! t .con .connected {
249
- t .con .m .Unlock ()
248
+ t .con .m .RUnlock ()
250
249
return nil
251
250
}
252
- t .con .m .Unlock ()
251
+ t .con .m .RUnlock ()
253
252
254
253
_ , err := io .Copy (w , reader )
255
254
if err != nil {
@@ -286,8 +285,10 @@ func (t *sshSmartSubtransport) createConn(addr string, sshConfig *ssh.ClientConf
286
285
return err
287
286
}
288
287
289
- t .con .conn = conn
288
+ t .con .m .Lock ()
289
+ t .con .connected = true
290
290
t .con .client = ssh .NewClient (c , chans , reqs )
291
+ t .con .m .Unlock ()
291
292
292
293
return nil
293
294
}
@@ -309,29 +310,24 @@ func (t *sshSmartSubtransport) Close() error {
309
310
if t .con .client != nil && t .stdin != nil {
310
311
_ = t .stdin .Close ()
311
312
}
312
- t .con . client = nil
313
+ t .stdin = nil
313
314
314
315
if t .con .session != nil {
315
316
traceLog .Info ("[ssh]: session.Close()" , "server" , t .addr )
316
317
_ = t .con .session .Close ()
317
318
}
318
319
t .con .session = nil
319
320
320
- return nil
321
- }
322
-
323
- func (t * sshSmartSubtransport ) Free () {
324
- traceLog .Info ("[ssh]: sshSmartSubtransport.Free()" )
325
321
if t .con .client != nil {
326
322
_ = t .con .client .Close ()
327
323
}
328
324
329
- if t .con .conn != nil {
330
- _ = t .con .conn .Close ()
331
- }
332
- t .con .m .Lock ()
333
325
t .con .connected = false
334
- t .con .m .Unlock ()
326
+
327
+ return nil
328
+ }
329
+
330
+ func (t * sshSmartSubtransport ) Free () {
335
331
}
336
332
337
333
type sshSmartSubtransportStream struct {
0 commit comments