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@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@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to