Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Tomb Wait blocks forever when no Goroutine is ever spawned. #21

Closed
jpittis opened this issue Oct 6, 2018 · 2 comments
Closed

Bug: Tomb Wait blocks forever when no Goroutine is ever spawned. #21

jpittis opened this issue Oct 6, 2018 · 2 comments

Comments

@jpittis
Copy link

jpittis commented Oct 6, 2018

If you call tmb.Wait() on a tomb that has never called tmb.Go, it blocks forever.

Here's a failing test case to reproduce the bug:

package tomb_test

import (
	"testing"
	"time"

	tomb "gopkg.in/tomb.v2"
)

func TestTombWaitDoesNotBlockWhenNoGoRoutinesSpawned(t *testing.T) {
	var tmb tomb.Tomb

	tmb.Kill(nil)

	done := make(chan struct{})
	go func() {
		err := tmb.Wait()
		if err != nil {
			t.Fatal(err)
		}
		close(done)
	}()

	select {
	case <-time.After(5 * time.Second):
		t.Fatal("Tomb did not exit in time.")
	case <-done:
		// Success!
	}
}

Here's the output of the test case using tomb d5d1b58:

$ go test
--- FAIL: TestTombWaitDoesNotBlockWhenNoGoRoutinesSpawned (5.00s)
	tomb_test.go:26: Tomb did not exit in time.
FAIL
exit status 1
FAIL	github.com/jpittis/tombbug	5.008s
@niemeyer
Copy link
Contributor

niemeyer commented Oct 8, 2018

That's by design. It prevents the potential race between Wait and Go. The proper way to use a tomb is to never hand it off for someone to Wait on it unless you do intend to use it.

@niemeyer niemeyer closed this as completed Oct 8, 2018
@jpittis
Copy link
Author

jpittis commented Oct 9, 2018

Appreciate the fast reply. Obviously there was another issue opened with the same subject.

Sorry about create a duplicate.

mardy added a commit to mardy/snapd that referenced this issue Dec 6, 2021
Do not initialize the loopTomb member until we are actually asking it to
run some routine. Otherwise the call to loopTomb.Wait() which we do when
stopping the Overlord could block forever.

This seems also to be the suggestion given in
go-tomb/tomb#21 to a similar problem.
mardy added a commit to mardy/snapd that referenced this issue Dec 6, 2021
Do not initialize the loopTomb member until we are actually asking it to
run some routine. Otherwise the call to loopTomb.Wait() which we do when
stopping the Overlord could block forever.

This seems also to be the suggestion given in
go-tomb/tomb#21 to a similar problem.
mardy added a commit to mardy/snapd that referenced this issue Dec 6, 2021
Do not initialize the loopTomb member until we are actually asking it to
run some routine. Otherwise the call to loopTomb.Wait() which we do when
stopping the Overlord could block forever.

This seems also to be the suggestion given in
go-tomb/tomb#21 to a similar problem.
mardy added a commit to mardy/snapd that referenced this issue Dec 13, 2021
Do not initialize the loopTomb member until we are actually asking it to
run some routine. Otherwise the call to loopTomb.Wait() which we do when
stopping the Overlord could block forever.

This seems also to be the suggestion given in
go-tomb/tomb#21 to a similar problem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants