Skip to content

Commit a935c22

Browse files
committed
Do not call observers within registrar lock to avoid recursive lock attempts
1 parent 97e830e commit a935c22

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

Sources/FoundationEssentials/NotificationCenter/NotificationCenter.swift

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,31 +119,29 @@ open class NotificationCenter: @unchecked Sendable {
119119
// TODO: Darwin calls observers in the order they were added, mixing wildcard and non-wildcard observers.
120120
// It's conceivable some users rely on that ordering.
121121

122-
// If 'M' is a Notification, users must manually manage isolation behaviors.
123-
// If 'M' is a Message, this will already be the right isolation.
124-
nonisolated(unsafe) let subject = subject
125-
nonisolated(unsafe) let message = message
126-
127-
registrar.withLock { _registrar in
122+
let observers = registrar.withLock { _registrar in
123+
var observers: [@Sendable (MessageBox) -> Void] = []
128124
let objectId = subject.map { ObjectIdentifier($0 as AnyObject) }
129-
let messageBox = MessageBox(message: message)
130125

131126
// Observers with 'name' and 'object'
132-
_registrar[name]?[objectId]?.values.forEach { $0(messageBox) }
127+
observers.append(contentsOf: _registrar[name]?[objectId]?.values ?? [])
133128

134129
// Observers with wildcard name and 'object'
135-
_registrar[nil]?[objectId]?.values.forEach { $0(messageBox) }
130+
observers.append(contentsOf: _registrar[nil]?[objectId]?.values ?? [])
136131

137-
// Observers with wildcard name and wildcard object
138132
if subject != nil {
139-
_registrar[nil]?[nil]?.values.forEach { $0(messageBox) }
133+
// Observers with wildcard name and wildcard object
134+
observers.append(contentsOf: _registrar[nil]?[nil]?.values ?? [])
135+
136+
// Observers with 'name' and wildcard object
137+
observers.append(contentsOf: _registrar[name]?[nil]?.values ?? [])
140138
}
141139

142-
// Observers with 'name' and wildcard object
143-
if subject != nil {
144-
_registrar[name]?[nil]?.values.forEach { $0(messageBox) }
145-
}
140+
return observers
146141
}
142+
143+
let messageBox = MessageBox(message: message)
144+
observers.forEach { $0(messageBox) }
147145
}
148146

149147
// For testing purposes only!

0 commit comments

Comments
 (0)