[swift-users] ThreadSanitizer: data race

Devin Coughlin dcoughlin at apple.com
Tue Jul 25 15:37:44 CDT 2017


Hi Thierry,

Are you initializing the mutex with pthread_mutex_init()? For example:

  pthread_mutex_init(&mutex, nil)

Just calling the default initializer for pthread_mutex_t is not sufficient — you won’t get any mutual exclusion. Thread Sanitizer should be complaining about this already (something like “Use of an uninitialized or destroyed mutex”).

If that doesn’t fix the problem, would you mind filing a bug at bugs.swift.org <http://bugs.swift.org/> and attaching your test project? That will help us narrow it down and we can continue the investigation there.

Thanks,
Devin


> On Jul 25, 2017, at 8:23 AM, Thierry Passeron via swift-users <swift-users at swift.org> wrote:
> 
> Hi everyone,
> 
> I don’t know if it’s the good place to ask for this, so if it’s not, please be kind enough to tell me where I should post this question.
> 
> I’m having a hard time figuring out why, since I activated ThreadSanitizer to my Xcode 9 scheme, I keep seeing race conditions when using OperationQueue and a custom BlockOperation subclass I made to deal with Asynchronous operations.
> 
> If I refer to the documentation on Operation, it says that isCancelled, isFinished, isExecuting properties must be thread safe since you never know from which thread they can be invoked. So I decided to go for a pthread_mutex_lock/unlock to protect the critical parts. For instance isFinished looks like this:
> 
> class AsyncBlockOperation : BlockOperation {
> 
>  enum State: String {
>    case  ready = "Ready",
>          executing = "Executing",
>          finished = "Finished"
>    fileprivate var keyPath: String {
>      return "is" + self.rawValue
>    }
>  }
> 
>  private var state: State = .ready
>  {
>    willSet {
>      willChangeValue(forKey: state.keyPath)
>      willChangeValue(forKey: newValue.keyPath)
>    }
>    didSet {
>      didChangeValue(forKey: oldValue.keyPath)
>      didChangeValue(forKey: state.keyPath)
>    }
>  }
> 
>  private var mutex = pthread_mutex_t()
> 
>  override var isFinished: Bool {
>    pthread_mutex_lock(&mutex)
>    defer { pthread_mutex_unlock(&mutex) }
>    return state == .finished
>  }
> 
> /* Same goes for isCancelled, and isExecuting… */
> }
> 
> I thought that the problem of « thread-safe » would be solved with these lock/unlock mutex but when an other thread accesses one of the these properties I get a data race warning by the ThreadSanitizer.
> 
> What do I do wrong?
> Is it possible that ThreadSanitizer reports a false positive? How should I debug this kind of issue? 
> 
> Any help would be much appreciated. I can provide a Xcode test project with a running example of this issue.
> 
> Thanks in advance.
> 
> Best regards,
> Thierry
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170725/a9d6ad20/attachment.html>


More information about the swift-users mailing list