0

I am trying to safely read/write data from multiple threads, like described here: Create thread safe array in Swift

Here's a snippet how I read data

    private let annotationsQueue = DispatchQueue(label: "myCustoLabel", attributes: .concurrent)
    private var unsafeAnnotations = [MapAnnotation]()
    private var annotations: [MapAnnotation] {
        var annotationsCopy: [MapAnnotation]!
        annotationsQueue.sync {
            annotationsCopy = self.unsafeAnnotations
        }
        return annotationsCopy
    }

My issue is that annotations is sometimes being called from DispatchQueue.main.async, which causes dead lock.

Here's are screenshot of stack trace, when I reach dead lock

enter image description here

My question is how should I handle such situation? Should I somehow force my annotationsQueue run on background thread? Or I should write my code, so annotations are never called from DispatchQueue.main.async?

Xernox
  • 1,706
  • 1
  • 23
  • 37
  • here you read some annotation data. right? `annotationsQueue.sync` –  May 03 '21 at 06:06
  • @JatinRB yes, I've added screenshot to highlight the issue – Xernox May 03 '21 at 06:43
  • for some reason low priority task it will not work so please try getter setter method like this https://stackoverflow.com/questions/35084754/objc-sync-enter-objc-sync-exit-not-working-with-dispatch-queue-priority-low –  May 03 '21 at 06:48
  • 1
    Pretty simple. Don’t use `sync`. – matt May 03 '21 at 07:08
  • @JatinRB you linked a question, not answer. And it seems my implementation is the same as in some answers – Xernox May 03 '21 at 07:18
  • @matt won't I have issues, when one thread will write and other will ready if I wont use sync? – Xernox May 03 '21 at 07:18
  • 1
    No, async on a serial queue is a form of locking. But you won’t be able to make this a computed property. – matt May 03 '21 at 07:41

1 Answers1

0

As you are creating concurrent queue can use dispatch barrier for read/write from multiple threads.

 private let annotationsQueue = DispatchQueue(label: "myCustoLabel", attributes: .concurrent)
   

private var unsafeAnnotations = [MapAnnotation]()

private var annotations: [MapAnnotation]? {
    var annotationsCopy: [MapAnnotation]!
    get {
      annotationsQueue.sync {
        return annotationsCopy
    }
    return nil

    }
    set {
      annotationsQueue.async(flag: .barrier) {
           annotationsCopy = self.unsafeAnnotations
       }
    }   

}
salman siddiqui
  • 882
  • 1
  • 10
  • 28