[go] net/http: wait for listeners to exit in Server.Close and Shutdown

24 views
Skip to first unread message

Damien Neil (Gerrit)

unread,
May 31, 2022, 5:53:13 PM5/31/22
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Damien Neil has uploaded this change for review.

View Change

net/http: wait for listeners to exit in Server.Close and Shutdown

Avoid race conditions when a new connection is accepted just after
Server.Close or Server.Shutdown is called by waiting for the
listener goroutines to exit before proceeding to clean up active
connections.

No test because the mechanism required to trigger the race condition
reliably requires such tight coupling to the Server internals that
any test would be quite fragile in the face of reasonable refactorings.

Fixes #48642
Updates #33313, #36819

Change-Id: I109a93362680991bf298e0a95637595dcaa884af
---
M src/net/http/server.go
1 file changed, 31 insertions(+), 0 deletions(-)

diff --git a/src/net/http/server.go b/src/net/http/server.go
index bc3a463..3611e9f 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -2690,6 +2690,8 @@
activeConn map[*conn]struct{}
doneChan chan struct{}
onShutdown []func()
+
+ listenerGroup sync.WaitGroup
}

func (s *Server) getDoneChan() <-chan struct{} {
@@ -2732,6 +2734,11 @@
defer srv.mu.Unlock()
srv.closeDoneChanLocked()
err := srv.closeListenersLocked()
+
+ srv.mu.Unlock()
+ srv.listenerGroup.Wait()
+ srv.mu.Lock()
+
for c := range srv.activeConn {
c.rwc.Close()
delete(srv.activeConn, c)
@@ -2778,6 +2785,7 @@
go f()
}
srv.mu.Unlock()
+ srv.listenerGroup.Wait()

pollIntervalBase := time.Millisecond
nextPollInterval := func() time.Duration {
@@ -3157,8 +3165,10 @@
return false
}
s.listeners[ln] = struct{}{}
+ s.listenerGroup.Add(1)
} else {
delete(s.listeners, ln)
+ s.listenerGroup.Done()
}
return true
}

To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
Gerrit-Change-Number: 409537
Gerrit-PatchSet: 1
Gerrit-Owner: Damien Neil <dn...@google.com>
Gerrit-MessageType: newchange

Damien Neil (Gerrit)

unread,
May 31, 2022, 5:54:17 PM5/31/22
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Patch set 1:Run-TryBot +1

View Change

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Comment-Date: Tue, 31 May 2022 21:54:13 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Ivan Kurnosov (Gerrit)

    unread,
    May 31, 2022, 6:04:56 PM5/31/22
    to Damien Neil, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

    Attention is currently required from: Damien Neil.

    View Change

    2 comments:

    • Patchset:

      • Patch Set #1:

        I think with this change it's possible to have a race between wg's Wait and Add calls.

    • File src/net/http/server.go:

      • Patch Set #1, Line 3168: s.listenerGroup.Add(1)

        Is this call not in race with two calls above to wait? `srv.listenerGroup.Wait()`?

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-Comment-Date: Tue, 31 May 2022 22:04:51 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    Damien Neil (Gerrit)

    unread,
    May 31, 2022, 6:11:41 PM5/31/22
    to goph...@pubsubhelper.golang.org, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Ivan Kurnosov.

    View Change

    1 comment:

    • File src/net/http/server.go:

      • Is this call not in race with two calls above to wait? `srv.listenerGroup. […]

        Add is only called if srv.inShutdown is not set, and srv.mu synchronizes access to srv.inShutdown between the Add and Wait calls.

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Comment-Date: Tue, 31 May 2022 22:11:37 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-MessageType: comment

    Ivan Kurnosov (Gerrit)

    unread,
    May 31, 2022, 6:20:40 PM5/31/22
    to Damien Neil, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gopher Robot, golang-co...@googlegroups.com

    Attention is currently required from: Brad Fitzpatrick, Damien Neil.

    View Change

    2 comments:

    • Patchset:

      • Patch Set #1:

        Right, I see now, thanks (PS: I'm not sure how to make my code comment as "Resolved" hopefully this comment marks it as such).

    • File src/net/http/server.go:

      • Add is only called if srv.inShutdown is not set, and srv.mu synchronizes access to srv. […]

        Ack

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-Attention: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Comment-Date: Tue, 31 May 2022 22:20:35 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Damien Neil <dn...@google.com>

    Alexander Yastrebov (Gerrit)

    unread,
    May 31, 2022, 6:54:38 PM5/31/22
    to Damien Neil, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Brad Fitzpatrick, Damien Neil.

    View Change

    1 comment:

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-Attention: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Comment-Date: Tue, 31 May 2022 22:54:34 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    Damien Neil (Gerrit)

    unread,
    May 31, 2022, 7:08:48 PM5/31/22
    to goph...@pubsubhelper.golang.org, Alexander Yastrebov, Brad Fitzpatrick, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Alexander Yastrebov, Brad Fitzpatrick.

    View Change

    1 comment:

    • File src/net/http/server.go:

      • This apparently allows to undo the https://golang. […]

        How is that? I'm not seeing it, but I'm probably missing something.

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-Attention: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Comment-Date: Tue, 31 May 2022 23:08:44 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-MessageType: comment

    Alexander Yastrebov (Gerrit)

    unread,
    May 31, 2022, 7:15:03 PM5/31/22
    to Damien Neil, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Brad Fitzpatrick, Damien Neil.

    View Change

    1 comment:

    • File src/net/http/server.go:

      • How is that? I'm not seeing it, but I'm probably missing something.

        It changed shutdown to wait for all listeners to be untracked (delete(s.listeners)) via defer in Serve.
        The listenerGroup barrier ensures the same.

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-Attention: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Comment-Date: Tue, 31 May 2022 23:14:57 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Alexander Yastrebov <yastreb...@gmail.com>
    Comment-In-Reply-To: Damien Neil <dn...@google.com>
    Gerrit-MessageType: comment

    Damien Neil (Gerrit)

    unread,
    May 31, 2022, 7:18:01 PM5/31/22
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Brad Fitzpatrick, Damien Neil.

    Damien Neil uploaded patch set #2 to this change.

    View Change

    The following approvals got outdated and were removed: Run-TryBot+1 by Damien Neil, TryBot-Result+1 by Gopher Robot

    net/http: wait for listeners to exit in Server.Close and Shutdown

    Avoid race conditions when a new connection is accepted just after
    Server.Close or Server.Shutdown is called by waiting for the
    listener goroutines to exit before proceeding to clean up active
    connections.

    No test because the mechanism required to trigger the race condition
    reliably requires such tight coupling to the Server internals that
    any test would be quite fragile in the face of reasonable refactorings.

    Fixes #48642
    Updates #33313, #36819

    Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    ---
    M src/net/http/server.go
    1 file changed, 32 insertions(+), 7 deletions(-)

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 2
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-Attention: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-MessageType: newpatchset

    Damien Neil (Gerrit)

    unread,
    May 31, 2022, 7:18:09 PM5/31/22
    to goph...@pubsubhelper.golang.org, Alexander Yastrebov, Brad Fitzpatrick, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Alexander Yastrebov, Brad Fitzpatrick.

    Patch set 1:Run-TryBot +1

    View Change

    1 comment:

    • File src/net/http/server.go:

      • It changed shutdown to wait for all listeners to be untracked (delete(s. […]

        Ah, I misunderstood what you were saying. Good point.

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 1
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-Attention: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Comment-Date: Tue, 31 May 2022 23:18:05 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes

    Brad Fitzpatrick (Gerrit)

    unread,
    May 31, 2022, 8:55:07 PM5/31/22
    to Damien Neil, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Alexander Yastrebov, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Alexander Yastrebov, Damien Neil.

    Patch set 2:Code-Review +2

    View Change

    3 comments:

    • File src/net/http/server.go:

      • Patch Set #2, Line 2738: srv.mu.Unlock()

        This looks like a mistake at first glance. Might be worth a comment so reader knows that the unlock-and-re-lock is intentional.

      • Patch Set #2, Line 2738: srv.mu.Unlock()

        Actually what's this letting happen? What's the Unlock for? For trackListener to able to run I guess? Leave a comment about that?

      • Patch Set #2, Line 3158: if s.shuttingDown() {

        And I guess this is the bit that prevents the Add(1) a few lines below from panicking on concurrent WaitGroup.Wait?

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 2
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-Comment-Date: Wed, 01 Jun 2022 00:55:04 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Damien Neil (Gerrit)

    unread,
    Jul 8, 2022, 12:13:38 PM7/8/22
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Alexander Yastrebov, Damien Neil.

    Damien Neil uploaded patch set #3 to this change.

    View Change

    net/http: wait for listeners to exit in Server.Close and Shutdown


    Avoid race conditions when a new connection is accepted just after
    Server.Close or Server.Shutdown is called by waiting for the
    listener goroutines to exit before proceeding to clean up active
    connections.

    No test because the mechanism required to trigger the race condition
    reliably requires such tight coupling to the Server internals that
    any test would be quite fragile in the face of reasonable refactorings.

    Fixes #48642
    Updates #33313, #36819

    Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    ---
    M src/net/http/server.go
    1 file changed, 36 insertions(+), 7 deletions(-)

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 3
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-Attention: Damien Neil <dn...@google.com>
    Gerrit-MessageType: newpatchset

    Damien Neil (Gerrit)

    unread,
    Jul 8, 2022, 12:13:54 PM7/8/22
    to goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Alexander Yastrebov, Gopher Robot, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Alexander Yastrebov.

    View Change

    3 comments:

    • File src/net/http/server.go:

      • This looks like a mistake at first glance. […]

        Done

      • Actually what's this letting happen? What's the Unlock for? For trackListener to able to run I guess […]

        Added some more comments here.

      • And I guess this is the bit that prevents the Add(1) a few lines below from panicking on concurrent […]

        Yes, exactly.

    To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
    Gerrit-Change-Number: 409537
    Gerrit-PatchSet: 3
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
    Gerrit-Attention: Alexander Yastrebov <yastreb...@gmail.com>
    Gerrit-Comment-Date: Fri, 08 Jul 2022 16:13:50 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-MessageType: comment

    Bryan Mills (Gerrit)

    unread,
    Jul 8, 2022, 12:34:36 PM7/8/22
    to Damien Neil, goph...@pubsubhelper.golang.org, Bryan Mills, Gopher Robot, Brad Fitzpatrick, Alexander Yastrebov, Ivan Kurnosov, golang-co...@googlegroups.com

    Attention is currently required from: Alexander Yastrebov, Damien Neil.

    Patch set 3:Code-Review +1

    View Change

      To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
      Gerrit-Change-Number: 409537
      Gerrit-PatchSet: 3
      Gerrit-Owner: Damien Neil <dn...@google.com>
      Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-Reviewer: Bryan Mills <bcm...@google.com>
      Gerrit-Reviewer: Damien Neil <dn...@google.com>
      Gerrit-Reviewer: Gopher Robot <go...@golang.org>
      Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
      Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
      Gerrit-Attention: Alexander Yastrebov <yastreb...@gmail.com>
      Gerrit-Attention: Damien Neil <dn...@google.com>
      Gerrit-Comment-Date: Fri, 08 Jul 2022 16:34:31 +0000

      Damien Neil (Gerrit)

      unread,
      Jul 8, 2022, 1:00:57 PM7/8/22
      to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Bryan Mills, Gopher Robot, Brad Fitzpatrick, Alexander Yastrebov, Ivan Kurnosov, golang-co...@googlegroups.com

      Damien Neil submitted this change.

      View Change



      2 is the latest approved patch-set.
      The change was submitted with unreviewed changes in the following files:

      ```
      The name of the file: src/net/http/server.go
      Insertions: 4, Deletions: 0.

      The diff is too large to show. Please review the diff.
      ```

      Approvals: Damien Neil: Run TryBots Brad Fitzpatrick: Looks good to me, approved Gopher Robot: TryBots succeeded Bryan Mills: Looks good to me, but someone else must approve
      net/http: wait for listeners to exit in Server.Close and Shutdown

      Avoid race conditions when a new connection is accepted just after
      Server.Close or Server.Shutdown is called by waiting for the
      listener goroutines to exit before proceeding to clean up active
      connections.

      No test because the mechanism required to trigger the race condition
      reliably requires such tight coupling to the Server internals that
      any test would be quite fragile in the face of reasonable refactorings.

      Fixes #48642
      Updates #33313, #36819

      Change-Id: I109a93362680991bf298e0a95637595dcaa884af
      Reviewed-on: https://go-review.googlesource.com/c/go/+/409537
      TryBot-Result: Gopher Robot <go...@golang.org>
      Run-TryBot: Damien Neil <dn...@google.com>
      Reviewed-by: Brad Fitzpatrick <brad...@golang.org>
      Reviewed-by: Bryan Mills <bcm...@google.com>
      ---
      M src/net/http/server.go
      1 file changed, 41 insertions(+), 7 deletions(-)

      diff --git a/src/net/http/server.go b/src/net/http/server.go
      index bc3a463..87dd412 100644

      --- a/src/net/http/server.go
      +++ b/src/net/http/server.go
      @@ -2690,6 +2690,8 @@
      activeConn map[*conn]struct{}
      doneChan chan struct{}
      onShutdown []func()
      +
      + listenerGroup sync.WaitGroup
      }

      func (s *Server) getDoneChan() <-chan struct{} {
      @@ -2732,6 +2734,15 @@

      defer srv.mu.Unlock()
      srv.closeDoneChanLocked()
      err := srv.closeListenersLocked()
      +
      +	// Unlock srv.mu while waiting for listenerGroup.
      + // The group Add and Done calls are made with srv.mu held,
      + // to avoid adding a new listener in the window between
      + // us setting inShutdown above and waiting here.

      + srv.mu.Unlock()
      + srv.listenerGroup.Wait()
      + srv.mu.Lock()
      +
      for c := range srv.activeConn {
      c.rwc.Close()
      delete(srv.activeConn, c)
      @@ -2778,6 +2789,7 @@

      go f()
      }
      srv.mu.Unlock()
      + srv.listenerGroup.Wait()

      pollIntervalBase := time.Millisecond
      nextPollInterval := func() time.Duration {
      @@ -2794,7 +2806,7 @@
      timer := time.NewTimer(nextPollInterval())
      defer timer.Stop()
      for {
      - if srv.closeIdleConns() && srv.numListeners() == 0 {
      + if srv.closeIdleConns() {
      return lnerr
      }
      select {
      @@ -2817,12 +2829,6 @@
      srv.mu.Unlock()
      }

      -func (s *Server) numListeners() int {
      - s.mu.Lock()
      - defer s.mu.Unlock()
      - return len(s.listeners)
      -}
      -
      // closeIdleConns closes all idle connections and reports whether the
      // server is quiescent.
      func (s *Server) closeIdleConns() bool {
      @@ -3157,8 +3163,10 @@

      return false
      }
      s.listeners[ln] = struct{}{}
      + s.listenerGroup.Add(1)
      } else {
      delete(s.listeners, ln)
      + s.listenerGroup.Done()
      }
      return true
      }

      To view, visit change 409537. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I109a93362680991bf298e0a95637595dcaa884af
      Gerrit-Change-Number: 409537
      Gerrit-PatchSet: 4
      Gerrit-Owner: Damien Neil <dn...@google.com>
      Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-Reviewer: Bryan Mills <bcm...@google.com>
      Gerrit-Reviewer: Damien Neil <dn...@google.com>
      Gerrit-Reviewer: Gopher Robot <go...@golang.org>
      Gerrit-CC: Alexander Yastrebov <yastreb...@gmail.com>
      Gerrit-CC: Ivan Kurnosov <zer...@gmail.com>
      Gerrit-MessageType: merged
      Reply all
      Reply to author
      Forward
      0 new messages