lib/protocol: Return from ClusterConfig when closed (#5752)

This commit is contained in:
Simon Frei 2019-05-29 12:14:00 +02:00 committed by Jakob Borg
parent e2a647a6a4
commit 6664e01acf
2 changed files with 28 additions and 2 deletions

View File

@ -332,8 +332,11 @@ func (c *rawConnection) Request(folder string, name string, offset int64, size i
// ClusterConfig sends the cluster configuration message to the peer. // ClusterConfig sends the cluster configuration message to the peer.
// It must be called just once (as per BEP), otherwise it will panic. // It must be called just once (as per BEP), otherwise it will panic.
func (c *rawConnection) ClusterConfig(config ClusterConfig) { func (c *rawConnection) ClusterConfig(config ClusterConfig) {
c.clusterConfigBox <- &config select {
close(c.clusterConfigBox) case c.clusterConfigBox <- &config:
close(c.clusterConfigBox)
case <-c.closed:
}
} }
func (c *rawConnection) Closed() bool { func (c *rawConnection) Closed() bool {

View File

@ -757,3 +757,26 @@ func TestSha256OfEmptyBlock(t *testing.T) {
} }
} }
} }
// TestClusterConfigAfterClose checks that ClusterConfig does not deadlock when
// ClusterConfig is called on a closed connection.
func TestClusterConfigAfterClose(t *testing.T) {
m := newTestModel()
c := NewConnection(c0ID, &testutils.BlockingRW{}, &testutils.BlockingRW{}, m, "name", CompressAlways).(wireFormatConnection).Connection.(*rawConnection)
c.Start()
c.internalClose(errManual)
done := make(chan struct{})
go func() {
c.ClusterConfig(ClusterConfig{})
close(done)
}()
select {
case <-done:
case <-time.After(time.Second):
t.Fatal("timed out before Cluster Config returned")
}
}