You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Jens Geyer (JIRA)" <ji...@apache.org> on 2017/07/01 14:03:01 UTC
[jira] [Assigned] (THRIFT-4243) Go TSimpleServer race on wait in
Stop() method
[ https://issues.apache.org/jira/browse/THRIFT-4243?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jens Geyer reassigned THRIFT-4243:
----------------------------------
Assignee: Zach Wasserman
> Go TSimpleServer race on wait in Stop() method
> ----------------------------------------------
>
> Key: THRIFT-4243
> URL: https://issues.apache.org/jira/browse/THRIFT-4243
> Project: Thrift
> Issue Type: Bug
> Components: Go - Library
> Reporter: Zach Wasserman
> Assignee: Zach Wasserman
>
> Synchronization issues with the use of {{sync.WaitGroup}} in the {{TSimpleServer}} implementation set off the race detector. Note the docs (https://godoc.org/sync#WaitGroup.Add) specify "calls with a positive delta that occur when the counter is zero must happen before a Wait".
> The following unit test demonstrates the issue:
> {code}
> package thrift
> import (
> "testing"
> "time"
> )
> type mockProcessor struct {
> ProcessFunc func(in, out TProtocol) (bool, TException)
> }
> func (m *mockProcessor) Process(in, out TProtocol) (bool, TException) {
> return m.ProcessFunc(in, out)
> }
> type mockServerTransport struct {
> ListenFunc func() error
> AcceptFunc func() (TTransport, error)
> CloseFunc func() error
> InterruptFunc func() error
> }
> func (m *mockServerTransport) Listen() error {
> return m.ListenFunc()
> }
> func (m *mockServerTransport) Accept() (TTransport, error) {
> return m.AcceptFunc()
> }
> func (m *mockServerTransport) Close() error {
> return m.CloseFunc()
> }
> func (m *mockServerTransport) Interrupt() error {
> return m.InterruptFunc()
> }
> type mockTTransport struct {
> TTransport
> }
> func (m *mockTTransport) Close() error {
> return nil
> }
> func TestWaitRace(t *testing.T) {
> proc := &mockProcessor{
> ProcessFunc: func(in, out TProtocol) (bool, TException) {
> return false, nil
> },
> }
> trans := &mockServerTransport{
> ListenFunc: func() error {
> return nil
> },
> AcceptFunc: func() (TTransport, error) {
> return &mockTTransport{}, nil
> },
> CloseFunc: func() error {
> return nil
> },
> InterruptFunc: func() error {
> return nil
> },
> }
> serv := NewTSimpleServer2(proc, trans)
> go serv.Serve()
> time.Sleep(1)
> serv.Stop()
> }
> {code}
> When run with the race detector, this test produces the following output:
> {code}
> go test -race -v -run TestWaitRace -count 1
> === RUN TestWaitRace
> ==================
> WARNING: DATA RACE
> Write at 0x00c4200849f4 by goroutine 6:
> internal/race.Write()
> /usr/local/Cellar/go/1.8/libexec/src/internal/race/race.go:41 +0x38
> sync.(*WaitGroup).Wait()
> /usr/local/Cellar/go/1.8/libexec/src/sync/waitgroup.go:129 +0x14b
> git.apache.org/thrift.git/lib/go/thrift.(*TSimpleServer).Stop.func1()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server.go:164 +0x9b
> sync.(*Once).Do()
> /usr/local/Cellar/go/1.8/libexec/src/sync/once.go:44 +0xe1
> git.apache.org/thrift.git/lib/go/thrift.(*TSimpleServer).Stop()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server.go:166 +0x8c
> git.apache.org/thrift.git/lib/go/thrift.TestWaitRace()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server_test.go:134 +0x1be
> testing.tRunner()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x107
> Previous read at 0x00c4200849f4 by goroutine 7:
> internal/race.Read()
> /usr/local/Cellar/go/1.8/libexec/src/internal/race/race.go:37 +0x38
> sync.(*WaitGroup).Add()
> /usr/local/Cellar/go/1.8/libexec/src/sync/waitgroup.go:71 +0x26b
> git.apache.org/thrift.git/lib/go/thrift.(*TSimpleServer).AcceptLoop()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server.go:139 +0xa6
> git.apache.org/thrift.git/lib/go/thrift.(*TSimpleServer).Serve()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server.go:154 +0x86
> Goroutine 6 (running) created at:
> testing.(*T).Run()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:697 +0x543
> testing.runTests.func1()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:882 +0xaa
> testing.tRunner()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x107
> testing.runTests()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:888 +0x4e0
> testing.(*M).Run()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:822 +0x1c3
> main.main()
> git.apache.org/thrift.git/lib/go/thrift/_test/_testmain.go:266 +0x20f
> Goroutine 7 (running) created at:
> git.apache.org/thrift.git/lib/go/thrift.TestWaitRace()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server_test.go:132 +0x1a3
> testing.tRunner()
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x107
> ==================
> --- FAIL: TestWaitRace (0.15s)
> testing.go:610: race detected during execution of test
> panic: sync: WaitGroup is reused before previous Wait has returned [recovered]
> panic: sync: WaitGroup is reused before previous Wait has returned
> goroutine 5 [running]:
> testing.tRunner.func1(0xc42006aea0)
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:622 +0x55f
> panic(0x14aea60, 0xc4201896a0)
> /usr/local/Cellar/go/1.8/libexec/src/runtime/panic.go:489 +0x2f0
> sync.(*WaitGroup).Wait(0xc4200849e8)
> /usr/local/Cellar/go/1.8/libexec/src/sync/waitgroup.go:133 +0x138
> git.apache.org/thrift.git/lib/go/thrift.(*TSimpleServer).Stop.func1()
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server.go:164 +0x9c
> sync.(*Once).Do(0x174ce68, 0xc42002bf00)
> /usr/local/Cellar/go/1.8/libexec/src/sync/once.go:44 +0xe2
> git.apache.org/thrift.git/lib/go/thrift.(*TSimpleServer).Stop(0xc420084980, 0x153af90, 0xc420084980)
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server.go:166 +0x8d
> git.apache.org/thrift.git/lib/go/thrift.TestWaitRace(0xc42006aea0)
> /Users/zwass/dev/go/src/git.apache.org/thrift.git/lib/go/thrift/simple_server_test.go:134 +0x1bf
> testing.tRunner(0xc42006aea0, 0x153b2b0)
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x108
> created by testing.(*T).Run
> /usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:697 +0x544
> exit status 2
> FAIL git.apache.org/thrift.git/lib/go/thrift 0.190s
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)