Article

Data Races

Detects unsynchronized access to mutable state across multiple threads.

Overview

This check detects when multiple threads access the same memory without synchronization and at least one access is a write.

Data Race with Producer and Consumer Functions

In the following example, the producer() function sets the global variable message, and the consumer() function waits for a flag to be set before printing the message. Because producer() is executed on one thread and consumer() is executed on another thread, order cannot be guaranteed, creating a data race.

var message: String? = nil
var messageIsAvailable: Bool = false
// Executed on Thread #1
func producer() {
    message = "hello!"
    messageIsAvailable = true
}
// Executed on Thread #2
func consumer() {
    repeat {
        usleep(1000)
    } while !messageIsAvailable
    print(message)
}

Solution

Use Dispatch APIs to coordinate access to message across multiple threads.

See Also

Thread Sanitizer Checks

Swift Access Races

Detects when multiple threads call a mutating method on the same structure, or pass a shared variable as inout without synchronization.

Races on Collections and Other APIs

Detects when a thread accesses a mutable object while another thread writes to that object, causing a data race.

Uninitialized Mutexes

Detects when a mutex is used before it’s initialized.

Thread Leaks

Detects when threads aren’t closed after use.