8000 Reimplement Wait method to make it can be called concurrently from mu… · etherscan-io/sftp@3a53acc · GitHub
[go: up one dir, main page]

Skip to content

Commit 3a53acc

Browse files
committed
Reimplement Wait method to make it can be called concurrently from multiple goroutines
1 parent fbf9e05 commit 3a53acc

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"os"
88
"path"
9+
"sync"
910
"sync/atomic"
1011
"syscall"
1112
"time"
@@ -122,7 +123,7 @@ func NewClientPipe(rd io.Reader, wr io.WriteCloser, opts ...ClientOption) (*Clie
122123
WriteCloser: wr,
123124
},
124125
inflight: make(map[uint32]chan<- result),
125-
errCh: make(chan error, 1),
126+
errCond: sync.NewCond(new(sync.Mutex)),
126127
},
127128
maxPacket: 1 << 15,
128129
maxConcurrentRequests: 64,

conn.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,21 @@ type clientConn struct {
3636
wg sync.WaitGroup
3737
sync.Mutex // protects inflight
3838
inflight map[uint32]chan<- result // outstanding requests
39-
errCh chan error
39+
40+
errCond *sync.Cond
41+
err error
4042
}
4143

4244
// Wait blocks until the conn has shut down, and return the error
43-
// causing the shutdown.
45+
// causing the shutdown. It can be called concurrently from multiple
46+
// goroutines.
4447
func (c *clientConn) Wait() error {
45-
return <-c.errCh
48+
c.errCond.L.Lock()
49+
defer c.errCond.L.Unlock()
50+
for c.err == nil {
51+
c.errCond.Wait()
52+
}
53+
return c.err
4654
}
4755

4856
// Close closes the SFTP session.
@@ -56,7 +64,10 @@ func (c *clientConn) loop() {
5664
err := c.recv()
5765
if err != nil {
5866
c.broadcastErr(err)
59-
c.errCh <- err
67+
c.errCond.L.Lock()
68+
c.err = err
69+
c.errCond.Broadcast()
70+
c.errCond.L.Unlock()
6071
}
6172
}
6273

0 commit comments

Comments
 (0)
0