Accessing variable across multiple threads - TSAN

Hi,

Overview

I have a variable onGoingFetchCount that I am accessing in the main thread and in the background thread.

Problem:

TSAN didn't catch this when the code was executed.

Question:

Am I missing something ?

Note:

  • I have checked the Thread Sanitizer checkbox (Edit Scheme > Run > Diagnostics > Thread Sanitizer checkbox)
  • Swift 5.2
  • Xcode - 11.4 (11E146)

Code:

class Test {
    
    var onGoingFetchCount = 0
    let queue = OperationQueue()
    
    func run() {
        
        fetch { value in
            print("value = \(value)")
        }
    }

    func fetch(completion: @escaping (String) -> ()) {
        
        onGoingFetchCount += 1 //Main thread
        
        let operation = BlockOperation {
            
            self.onGoingFetchCount -= 1 //Background thread
            
            completion("testing")
        }
        
        queue.addOperation(operation)
    }
}

let test = Test()

test.run()

You are accessing it on both threads, but you're not doing it at the same time, which is totally fine and safe.

You change onGoingFetchCount on main thread, and only then you create and run the background operation.

If you try to modify onGoingFetchCount on main thread at the same time as the background thread might be running you will be doing bad stuff and tsan will complain:

import Foundation

class Test {

    var onGoingFetchCount = 0
    let queue = OperationQueue()

    func run() {

        fetch { value in
            print("value = \(value)")
        }
    }

    func fetch(completion: @escaping (String) -> ()) {
        let operation = BlockOperation {

            self.onGoingFetchCount -= 1 //Background thread

            completion("testing")
        }
        queue.addOperation(operation)

        onGoingFetchCount += 1 //Main thread

    }
}

let test = Test()

test.run()
2 Likes

@cukr Thank you so much !!! I was breaking my head over it.

You are spot on, I incremented the value even before the operation was added to the queue, so there is no issue.