TUN-1510: Wrap the close() in sync.Once.Do

This commit is contained in:
Adam Chalmers 2019-02-19 11:40:49 -06:00
parent e025a4cd7b
commit 7475e3e487
2 changed files with 7 additions and 5 deletions

View File

@ -181,6 +181,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
listeners := gracenet.Net{} listeners := gracenet.Net{}
errC := make(chan error) errC := make(chan error)
connectedSignal := make(chan struct{}) connectedSignal := make(chan struct{})
closeConnOnce := sync.Once{}
dnsReadySignal := make(chan struct{}) dnsReadySignal := make(chan struct{})
if c.String("config") == "" { if c.String("config") == "" {
@ -280,7 +281,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
// Serve DNS proxy stand-alone if no hostname or tag or app is going to run // Serve DNS proxy stand-alone if no hostname or tag or app is going to run
if dnsProxyStandAlone(c) { if dnsProxyStandAlone(c) {
close(connectedSignal) closeConnOnce.Do(func() { close(connectedSignal) })
// no grace period, handle SIGINT/SIGTERM immediately // no grace period, handle SIGINT/SIGTERM immediately
return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, 0) return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, 0)
} }
@ -315,6 +316,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
} }
tunnelConfig, err := prepareTunnelConfig(c, buildInfo, version, logger, transportLogger) tunnelConfig, err := prepareTunnelConfig(c, buildInfo, version, logger, transportLogger)
tunnelConfig.CloseConnOnce = &closeConnOnce
if err != nil { if err != nil {
return err return err
} }

View File

@ -11,10 +11,9 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"golang.org/x/sync/errgroup"
"github.com/cloudflare/cloudflared/h2mux" "github.com/cloudflare/cloudflared/h2mux"
"github.com/cloudflare/cloudflared/tunnelrpc" "github.com/cloudflare/cloudflared/tunnelrpc"
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs" tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
@ -26,6 +25,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
_ "github.com/prometheus/client_golang/prometheus" _ "github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
rpc "zombiezen.com/go/capnproto2/rpc" rpc "zombiezen.com/go/capnproto2/rpc"
) )
@ -64,6 +64,7 @@ type TunnelConfig struct {
WSGI bool WSGI bool
CompressionQuality uint64 CompressionQuality uint64
IncidentLookup IncidentLookup IncidentLookup IncidentLookup
CloseConnOnce *sync.Once // Used to close connectedSignal no more than once
} }
type dialError struct { type dialError struct {
@ -161,11 +162,10 @@ func ServeTunnelLoop(ctx context.Context,
config.Metrics.incrementHaConnections() config.Metrics.incrementHaConnections()
defer config.Metrics.decrementHaConnections() defer config.Metrics.decrementHaConnections()
backoff := BackoffHandler{MaxRetries: config.Retries} backoff := BackoffHandler{MaxRetries: config.Retries}
// Used to close connectedSignal no more than once
connectedFuse := h2mux.NewBooleanFuse() connectedFuse := h2mux.NewBooleanFuse()
go func() { go func() {
if connectedFuse.Await() { if connectedFuse.Await() {
close(connectedSignal) config.CloseConnOnce.Do(func() { close(connectedSignal) })
} }
}() }()
// Ensure the above goroutine will terminate if we return without connecting // Ensure the above goroutine will terminate if we return without connecting