Skip to content

[SR-192] Weak properties are not thread safe when reading #42814

Closed
@mikeash

Description

@mikeash
Previous ID SR-192
Radar None
Original Reporter @mikeash
Type Bug
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 8
Component/s
Labels Bug, Runtime
Assignee @glessard
Priority Medium

md5: e84790d9452452d03d108981ba9ce226

Issue Description:

The current implementation of weak references has a race condition when multiple threads read the same weak reference to a deallocating object simultaneously. Since this is semantically read-only access (even if writing occurs under the hood), this should be made safe.

The bug itself lies in the swift_weakLoadStrong function. If two threads simultaneously enter this function with the same weak reference and object->refCount.isDeallocating() is true, the threads will race. This can result in calling swift_unownedRelease() twice resulting in a double-free or worse, or it could result in one thread calling swift_tryRetain() on a deallocated object.

Here is a test case which demonstrates the problem:

import Foundation

class Target {}

class WeakHolder {
   weak var weak: Target?
}

for i in 0..<1000000 {
   print(i)
   let holder = WeakHolder()
   holder.weak = Target()
   dispatch_async(dispatch_get_global_queue(0, 0), {
       let _ = holder.weak
   })
   dispatch_async(dispatch_get_global_queue(0, 0), {
       let _ = holder.weak
   })
}

Metadata

Metadata

Assignees

Labels

bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.runtimeThe Swift Runtime

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions