Skip to content

Commit 6fc0733

Browse files
committed
minor
1 parent ee5f3d4 commit 6fc0733

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

Common/Cpp/ListenerSet.h

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,22 @@ class ListenerSet{
3939
return m_count.load(std::memory_order_acquire);
4040
}
4141

42-
// Add a new listener. This will never fail unless it throws.
43-
// Deadlocking is not possible since there's only one local lock.
42+
// Add a new listener. This is always safe as it will never fail unless it
43+
// throws. Deadlocking is not possible since there's only one local lock.
4444
void add(ListenerType& listener);
4545

46-
// Remove a listener. This will deadlock if a listener tries to remove
47-
// from inside a callback.
48-
void remove(ListenerType& listener);
46+
// Remove a listener. This will block if the listener being removed is
47+
// running a callback from this class.
48+
// Therefore, this will deadlock if a listener tries to remove itself from
49+
// inside its own callback.
50+
void remove(ListenerType& listener) noexcept;
4951

50-
// Same as above, but will return false if it needs to wait.
51-
// This can never deadlock.
52-
bool try_remove(ListenerType& listener);
52+
// Remove a listener (non-blocking). This will return false if it needs to
53+
// wait. This function is always safe and will never deadlock.
54+
bool try_remove(ListenerType& listener) noexcept;
5355

56+
57+
public:
5458
template <typename Function, class... Args>
5559
void run_method(Function function, Args&&... args);
5660

@@ -121,10 +125,10 @@ void ListenerSet<ListenerType>::add(ListenerType& listener){
121125
}
122126
node.next = m_list;
123127
m_list = &node;
124-
m_count.store(m_listeners.size(), std::memory_order_relaxed);
128+
m_count.store(m_listeners.size(), std::memory_order_release);
125129
}
126130
template <typename ListenerType>
127-
void ListenerSet<ListenerType>::remove(ListenerType& listener){
131+
void ListenerSet<ListenerType>::remove(ListenerType& listener) noexcept{
128132
#ifdef PA_DEBUG_ListenerSet
129133
auto scope = m_sanitizer.check_scope();
130134
#endif
@@ -142,7 +146,9 @@ void ListenerSet<ListenerType>::remove(ListenerType& listener){
142146
#endif
143147

144148
if (!node.lock.try_acquire_write()){
145-
std::cout << "ListenerSet::remove(): Retry inner." << std::endl;
149+
try{
150+
std::cout << "ListenerSet::remove(): Retry inner." << std::endl;
151+
}catch (...){}
146152
continue;
147153
}
148154

@@ -161,15 +167,15 @@ void ListenerSet<ListenerType>::remove(ListenerType& listener){
161167
#endif
162168

163169
m_listeners.erase(iter);
164-
m_count.store(m_listeners.size(), std::memory_order_relaxed);
170+
m_count.store(m_listeners.size(), std::memory_order_release);
165171
return;
166172
}
167173
}
168174

169175

170176

171177
template <typename ListenerType>
172-
bool ListenerSet<ListenerType>::try_remove(ListenerType& listener){
178+
bool ListenerSet<ListenerType>::try_remove(ListenerType& listener) noexcept{
173179
#ifdef PA_DEBUG_ListenerSet
174180
auto scope = m_sanitizer.check_scope();
175181
#endif
@@ -184,7 +190,9 @@ bool ListenerSet<ListenerType>::try_remove(ListenerType& listener){
184190

185191
Node& node = iter->second;
186192
if (!node.lock.try_acquire_write()){
187-
std::cout << "ListenerSet::try_remove(): Fail inner." << std::endl;
193+
try{
194+
std::cout << "ListenerSet::try_remove(): Fail inner." << std::endl;
195+
}catch (...){}
188196
return false;
189197
}
190198

@@ -205,7 +213,7 @@ bool ListenerSet<ListenerType>::try_remove(ListenerType& listener){
205213
#endif
206214

207215
m_listeners.erase(iter);
208-
m_count.store(m_listeners.size(), std::memory_order_relaxed);
216+
m_count.store(m_listeners.size(), std::memory_order_release);
209217
m_lock.unlock_write();
210218
return true;
211219
}

0 commit comments

Comments
 (0)