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

Race condition on FunctionReturns while simultaneously calling Function #145

Closed
NilsJPWerner opened this issue Sep 19, 2019 · 2 comments
Closed

Comments

@NilsJPWerner
Copy link
Contributor

I run into a race condition when I have a go routine constantly calling a function while simultaneously changing the return value of the function with functionReturns.

I have pinpointed the issue to the faked function unlocking its mutex too early. The faked function should only unlock the function mutex after checking whether the function stub is nil. In the current version both the main function and the functionReturns can access the stub at the same time causing test failures.

func (fake *FakeService) RaceClosed(arg1 string, arg2 string, arg3 int) (bool, error) {
	fake.raceClosedMutex.Lock()
	ret, specificReturn := fake.raceClosedReturnsOnCall[len(fake.raceClosedArgsForCall)]
	fake.raceClosedArgsForCall = append(fake.raceClosedArgsForCall, struct {
		arg1 string
		arg2 string
		arg3 int
	}{arg1, arg2, arg3})
	fake.recordInvocation("RaceClosed", []interface{}{arg1, arg2, arg3})  
	fake.raceClosedMutex.Unlock()         // This needs to be moved to later in the function
	if fake.RaceClosedStub != nil {       // This line is where data races happen
		return fake.RaceClosedStub(arg1, arg2, arg3)
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	fakeReturns := fake.raceClosedReturns
	return fakeReturns.result1, fakeReturns.result2
}

func (fake *FakeService) RaceClosedReturns(result1 bool, result2 error) {
	fake.raceClosedMutex.Lock()
	defer fake.raceClosedMutex.Unlock()
	fake.RaceClosedStub = nil        // This line is the other side of the data race
	fake.raceClosedReturns = struct {
		result1 bool
		result2 error
	}{result1, result2}
}

I can create a PR to move this line later: https://github.com/maxbrunsfeld/counterfeiter/blob/master/generator/interface_template.go#L70 of to make it deferred.

@NilsJPWerner
Copy link
Contributor Author

If I create a PR will someone merge it in?

@NilsJPWerner
Copy link
Contributor Author

Bump

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

1 participant