-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
| 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
})
}