{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/24803","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/24803/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/24803/comments","events_url":"https://api.github.com/repos/golang/go/issues/24803/events","html_url":"https://github.com/golang/go/issues/24803","id":313169598,"number":24803,"title":"net/http: shutdown on http.Server serving through net.Listener closes listener twice","user":{"login":"tdewolff","id":5563166,"avatar_url":"https://avatars1.githubusercontent.com/u/5563166?v=4","gravatar_id":"","url":"https://api.github.com/users/tdewolff","html_url":"https://github.com/tdewolff","followers_url":"https://api.github.com/users/tdewolff/followers","following_url":"https://api.github.com/users/tdewolff/following{/other_user}","gists_url":"https://api.github.com/users/tdewolff/gists{/gist_id}","starred_url":"https://api.github.com/users/tdewolff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tdewolff/subscriptions","organizations_url":"https://api.github.com/users/tdewolff/orgs","repos_url":"https://api.github.com/users/tdewolff/repos","events_url":"https://api.github.com/users/tdewolff/events{/privacy}","received_events_url":"https://api.github.com/users/tdewolff/received_events","type":"User","site_admin":false},"labels":[{"id":373402289,"url":"https://api.github.com/repos/golang/go/labels/NeedsInvestigation","name":"NeedsInvestigation","color":"ededed","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/62","html_url":"https://github.com/golang/go/milestone/62","labels_url":"https://api.github.com/repos/golang/go/milestones/62/labels","id":2827591,"number":62,"title":"Go1.11","description":"","creator":{"login":"rsc","id":104030,"avatar_url":"https://avatars1.githubusercontent.com/u/104030?v=4","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":894,"closed_issues":290,"state":"open","created_at":"2017-10-10T13:39:17Z","updated_at":"2018-04-11T09:51:49Z","due_on":"2018-07-31T07:00:00Z","closed_at":null},"comments":2,"created_at":"2018-04-11T04:27:22Z","updated_at":"2018-04-11T10:11:37Z","closed_at":null,"author_association":"NONE","body":"Please answer these questions before submitting your issue. Thanks!\r\n\r\n\r\n### What version of Go are you using (`go version`)?\r\ngo version go1.10.1 linux/amd64\r\n\r\n### Does this issue reproduce with the latest release?\r\nYes\r\n\r\n### What operating system and processor architecture are you using (`go env`)?\r\n```\r\nGOARCH=\"amd64\"\r\nGOBIN=\"\"\r\nGOCACHE=\"/home/taco/.cache/go-build\"\r\nGOEXE=\"\"\r\nGOHOSTARCH=\"amd64\"\r\nGOHOSTOS=\"linux\"\r\nGOOS=\"linux\"\r\nGOPATH=\"/home/taco/go\"\r\nGORACE=\"\"\r\nGOROOT=\"/usr/lib/go\"\r\nGOTMPDIR=\"\"\r\nGOTOOLDIR=\"/usr/lib/go/pkg/tool/linux_amd64\"\r\nGCCGO=\"gccgo\"\r\nCC=\"gcc\"\r\nCXX=\"g++\"\r\nCGO_ENABLED=\"1\"\r\nCGO_CFLAGS=\"-g -O2\"\r\nCGO_CPPFLAGS=\"\"\r\nCGO_CXXFLAGS=\"-g -O2\"\r\nCGO_FFLAGS=\"-g -O2\"\r\nCGO_LDFLAGS=\"-g -O2\"\r\nPKG_CONFIG=\"pkg-config\"\r\nGOGCCFLAGS=\"-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build151412356=/tmp/go-build -gno-record-gcc-switches\"\r\n```\r\n\r\n### What did you do?\r\nWhen I run the following code, the listener is closed twice:\r\n\r\n``` go\r\npackage main\r\n\r\nimport (\r\n\t\"context\"\r\n\t\"fmt\"\r\n\t\"net\"\r\n\t\"net/http\"\r\n\t\"time\"\r\n)\r\n\r\ntype Listener struct {\r\n\tnet.Listener\r\n}\r\n\r\nfunc (l *Listener) Close() error {\r\n\tfmt.Println(\"close\")\r\n\treturn l.Listener.Close()\r\n}\r\n\r\nfunc main() {\r\n\tln, _ := net.Listen(\"tcp\", \"localhost:9999\")\r\n\tlistener := &Listener{ln}\r\n\r\n\tserver := &http.Server{}\r\n\tgo func() {\r\n\t\terr := server.Serve(listener)\r\n\t\tfmt.Println(\"Serve:\", err)\r\n\t}()\r\n\r\n\ttime.Sleep(time.Second) // make sure it starts Serving\r\n\r\n\tserver.Shutdown(context.Background())\r\n\r\n\ttime.Sleep(time.Second) // make sure to exit Serve and print error before exit\r\n}\r\n```\r\n\r\nThe problem appears to be in `http/server.go`, where `Shutdown` will call `srv.closeListenersLocked` which closes our listener. But as `Serve` exits, the first row in that function defines a `defer l.Close()` that closes the listener as well! I think the latter should go, if I understand it correctly.\r\n\r\n### What did you expect to see?\r\nI expected the listener to be closed only once, this is causing double closes on underlying structures in our production.\r\n\r\n### What did you see instead?\r\nYou will notice that `Close` is called twice.\r\n"},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/380400575","html_url":"https://github.com/golang/go/issues/24803#issuecomment-380400575","issue_url":"https://api.github.com/repos/golang/go/issues/24803","id":380400575,"user":{"login":"gregory-m","id":148958,"avatar_url":"https://avatars1.githubusercontent.com/u/148958?v=4","gravatar_id":"","url":"https://api.github.com/users/gregory-m","html_url":"https://github.com/gregory-m","followers_url":"https://api.github.com/users/gregory-m/followers","following_url":"https://api.github.com/users/gregory-m/following{/other_user}","gists_url":"https://api.github.com/users/gregory-m/gists{/gist_id}","starred_url":"https://api.github.com/users/gregory-m/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gregory-m/subscriptions","organizations_url":"https://api.github.com/users/gregory-m/orgs","repos_url":"https://api.github.com/users/gregory-m/repos","events_url":"https://api.github.com/users/gregory-m/events{/privacy}","received_events_url":"https://api.github.com/users/gregory-m/received_events","type":"User","site_admin":false},"created_at":"2018-04-11T10:11:37Z","updated_at":"2018-04-11T10:11:37Z","author_association":"CONTRIBUTOR","body":"The first `Close()` is form: https://github.com/golang/go/blob/cf7760360ed5ed5ae3d38e626eaf913329d16778/src/net/http/server.go#L2624\r\n\r\nThe second is from: \r\nhttps://github.com/golang/go/blob/cf7760360ed5ed5ae3d38e626eaf913329d16778/src/net/http/server.go#L2758\r\n\r\nThe `defer l.Close()` in `Serve` function was added 7 years ago: 876e9d1b89cf87f3791153fa9472142cd5294223 and I doubt if its necessary, because before `Server.Close()` and `Server.Shutdown()` was added closing underlying listener was the only way to shutdown server."}}
{"actor":{"display_login":"gregory-m"}}