Skip to content

Commit 9cd976a

Browse files
committed
Fix error printing spam. Comments.
1 parent 6fc0733 commit 9cd976a

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

Common/Cpp/ListenerSet.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ class ListenerSet{
6666

6767
mutable SpinLock m_lock;
6868

69+
// The data structure here is an intrusive map where the nodes form a
70+
// linked-list. The map provides a fast way to add/remove listeners while
71+
// the linked-list is the main method of iterating the listeners.
72+
//
73+
// Iterating listeners to fire callbacks is completely thread-safe as they
74+
// do not modify the structure of the container. OTOH, adding/removing does
75+
// modify the data structure.
76+
//
77+
// "m_lock" protects the structure of container. You cannot change the
78+
// map or the linked list without holding this lock. When iterating the
79+
// nodes to fire callbacks, you must hold this lock when moving from one
80+
// node to the next to prevent the points from changing from under you.
81+
//
82+
// To prevent a listener from being removed while its callback is running,
83+
// there is a lock on each node. The contract for removing is a listener is
84+
// that when "remove_listener()" returns, this class holds no more
85+
// references to it and thus is the listener is safe to destroy.
86+
//
6987
struct Node{
7088
SpinLock lock;
7189
ListenerType& listener;
@@ -112,7 +130,7 @@ void ListenerSet<ListenerType>::add(ListenerType& listener){
112130
std::piecewise_construct,
113131
std::forward_as_tuple(&listener),
114132
std::forward_as_tuple(*this, listener)
115-
);
133+
);
116134
if (!ret.second){
117135
return;
118136
}
@@ -132,6 +150,9 @@ void ListenerSet<ListenerType>::remove(ListenerType& listener) noexcept{
132150
#ifdef PA_DEBUG_ListenerSet
133151
auto scope = m_sanitizer.check_scope();
134152
#endif
153+
154+
bool printed = false;
155+
135156
while (true){
136157
WriteSpinLock lg(m_lock);
137158
auto iter = m_listeners.find(&listener);
@@ -146,9 +167,12 @@ void ListenerSet<ListenerType>::remove(ListenerType& listener) noexcept{
146167
#endif
147168

148169
if (!node.lock.try_acquire_write()){
149-
try{
150-
std::cout << "ListenerSet::remove(): Retry inner." << std::endl;
151-
}catch (...){}
170+
if (!printed){
171+
try{
172+
std::cout << "ListenerSet::remove(): Retry inner." << std::endl;
173+
}catch (...){}
174+
printed = true;
175+
}
152176
continue;
153177
}
154178

0 commit comments

Comments
 (0)