Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • B Bolts-ObjC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 34
    • Issues 34
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 7
    • Merge requests 7
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • BoltsFramework
  • Bolts-ObjC
  • Issues
  • #302
Closed
Open
Issue created Aug 24, 2017 by tealshift@tealshift

Race Conditions

Issue reported in Parse SDK GitHub: https://github.com/parse-community/Parse-SDK-iOS-OSX/issues/1175 Insights courtesy of @flovilmart :

Seems that the issue is in Bolts and not the Parse SDK. I ran the thread sanitizer and realized this:

Upon callback, setting the result on a particular thread

- (BOOL)trySetResult:(nullable id)result {
    @synchronized(self.lock) {
        if (self.completed) {
            return NO;
        }
        self.completed = YES; // <-- HERE
        _result = result;
        [self runContinuations];
        return YES;
    }
}

when a task is marked waitUntilFinished

- (void)waitUntilFinished {
    if ([NSThread isMainThread]) {
        [self warnOperationOnMainThread];
    }

    @synchronized(self.lock) {
        if (self.completed) {
            return;
        }
        [self.condition lock];
    }
    // TODO: (nlutsenko) Restructure this to use Bolts-Swift thread access synchronization architecture
    // In the meantime, it's absolutely safe to get `_completed` aka an ivar, as long as it's a `BOOL` aka less than word size.
    while (!_completed) { // <- READ data from there.
        [self.condition wait];
    }
    [self.condition unlock];
}

Also there seems to be a note about it:

// TODO: (nlutsenko) Restructure this to use Bolts-Swift thread access synchronization architecture // In the meantime, it's absolutely safe to get _completed aka an ivar, as long as it's a BOOL aka less than word size.

We see other data races in bolts related to the concurrency model employed, mostly read on BOOL completed that are concurrent and not on the same thread.

Assignee
Assign to
Time tracking