MCPcopy
hub / github.com/tailscale/tailscale / close

Method close

tsnet/tsnet.go:614–668  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

612}
613
614func (s *Server) close() {
615 // Close listeners under s.mu, then release before the heavy shutdown
616 // operations. We must not hold s.mu during netstack.Close, lb.Shutdown,
617 // etc. because callbacks from gVisor (e.g. getTCPHandlerForFlow)
618 // acquire s.mu, and waiting for those goroutines while holding the lock
619 // would deadlock.
620 s.mu.Lock()
621 for _, ln := range s.listeners {
622 ln.closeLocked()
623 }
624 s.mu.Unlock()
625
626 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
627 defer cancel()
628 var wg sync.WaitGroup
629 wg.Go(func() {
630 // Perform a best-effort final flush.
631 if s.logtail != nil {
632 s.logtail.Shutdown(ctx)
633 }
634 if s.logbuffer != nil {
635 s.logbuffer.Close()
636 }
637 })
638 wg.Go(func() {
639 if s.localAPIServer != nil {
640 s.localAPIServer.Shutdown(ctx)
641 }
642 })
643
644 if s.shutdownCancel != nil {
645 s.shutdownCancel()
646 }
647 if s.netstack != nil {
648 s.netstack.Close()
649 }
650 if s.lb != nil {
651 s.lb.Shutdown()
652 }
653 if s.netMon != nil {
654 s.netMon.Close()
655 }
656 if s.dialer != nil {
657 s.dialer.Close()
658 }
659 if s.localAPIListener != nil {
660 s.localAPIListener.Close()
661 }
662 if s.loopbackListener != nil {
663 s.loopbackListener.Close()
664 }
665
666 wg.Wait()
667 s.sys.Bus.Get().Close()
668}
669
670func (s *Server) doInit() {
671 s.shutdownCtx, s.shutdownCancel = context.WithCancel(context.Background())

Callers 1

CloseMethod · 0.95

Calls 8

GoMethod · 0.80
LockMethod · 0.65
UnlockMethod · 0.65
ShutdownMethod · 0.65
CloseMethod · 0.65
WaitMethod · 0.65
GetMethod · 0.65
closeLockedMethod · 0.45

Tested by

no test coverage detected