forked from quic-go/quic-go
only close the client once
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
@@ -22,6 +23,7 @@ type Client struct {
|
|||||||
connectionID protocol.ConnectionID
|
connectionID protocol.ConnectionID
|
||||||
version protocol.VersionNumber
|
version protocol.VersionNumber
|
||||||
versionNegotiated bool
|
versionNegotiated bool
|
||||||
|
closed uint32 // atomic bool
|
||||||
|
|
||||||
cryptoChangeCallback CryptoChangeCallback
|
cryptoChangeCallback CryptoChangeCallback
|
||||||
versionNegotiateCallback VersionNegotiateCallback
|
versionNegotiateCallback VersionNegotiateCallback
|
||||||
@@ -111,6 +113,11 @@ func (c *Client) OpenStream(id protocol.StreamID) (utils.Stream, error) {
|
|||||||
|
|
||||||
// Close closes the connection
|
// Close closes the connection
|
||||||
func (c *Client) Close(e error) error {
|
func (c *Client) Close(e error) error {
|
||||||
|
// Only close once
|
||||||
|
if !atomic.CompareAndSwapUint32(&c.closed, 0, 1) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
_ = c.session.Close(e)
|
_ = c.session.Close(e)
|
||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,11 +77,20 @@ var _ = Describe("Client", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Eventually(session.closed).Should(BeTrue())
|
Eventually(session.closed).Should(BeTrue())
|
||||||
Expect(session.closeReason).To(MatchError(testErr))
|
Expect(session.closeReason).To(MatchError(testErr))
|
||||||
|
Expect(client.closed).To(Equal(uint32(1)))
|
||||||
Eventually(func() bool { return stoppedListening }).Should(BeTrue())
|
Eventually(func() bool { return stoppedListening }).Should(BeTrue())
|
||||||
Eventually(runtime.NumGoroutine()).Should(Equal(numGoRoutines))
|
Eventually(runtime.NumGoroutine()).Should(Equal(numGoRoutines))
|
||||||
close(done)
|
close(done)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("only closes the client once", func() {
|
||||||
|
client.closed = 1
|
||||||
|
err := client.Close(errors.New("test error"))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Eventually(session.closed).Should(BeFalse())
|
||||||
|
Expect(session.closeReason).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
It("creates new sessions with the right parameters", func() {
|
It("creates new sessions with the right parameters", func() {
|
||||||
startUDPConn()
|
startUDPConn()
|
||||||
client.session = nil
|
client.session = nil
|
||||||
|
|||||||
Reference in New Issue
Block a user