mirror of
https://github.com/hyprwm/hyprutils.git
synced 2026-05-05 20:58:00 +02:00
signals: use tuple reference and check if listeners is empty
use forward_as_tuple as ít creates a temporary tuple reference instead of copying/moving each argument. also if guard the emitInternal to only create locals if there is actually any listeners.
This commit is contained in:
parent
5ac060bfcf
commit
8ca26cee4d
2 changed files with 27 additions and 22 deletions
|
|
@ -36,7 +36,7 @@ namespace Hyprutils {
|
|||
if constexpr (sizeof...(Args) == 0)
|
||||
emitInternal(nullptr);
|
||||
else {
|
||||
auto argsTuple = std::tuple<RefArg<Args>...>(args...);
|
||||
auto argsTuple = std::forward_as_tuple(args...);
|
||||
|
||||
if constexpr (sizeof...(Args) == 1)
|
||||
// NOLINTNEXTLINE: const is reapplied by handler invocation if required
|
||||
|
|
|
|||
|
|
@ -10,33 +10,38 @@ using namespace Hyprutils::Memory;
|
|||
#define WP CWeakPointer
|
||||
|
||||
void Hyprutils::Signal::CSignalBase::emitInternal(void* args) {
|
||||
std::vector<SP<CSignalListener>> listeners;
|
||||
listeners.reserve(m_vListeners.size());
|
||||
for (auto& l : m_vListeners) {
|
||||
if (l.expired())
|
||||
continue;
|
||||
if (!m_vListeners.empty()) {
|
||||
std::vector<SP<CSignalListener>> listeners;
|
||||
listeners.reserve(m_vListeners.size());
|
||||
|
||||
listeners.emplace_back(l.lock());
|
||||
for (const auto& l : m_vListeners) {
|
||||
if (l.expired())
|
||||
continue;
|
||||
|
||||
listeners.emplace_back(l.lock());
|
||||
}
|
||||
|
||||
for (const auto& l : listeners) {
|
||||
// if there is only one lock, it means the event is only held by the listeners
|
||||
// vector and was removed during our iteration
|
||||
if (l.strongRef() == 1)
|
||||
continue;
|
||||
|
||||
l->emitInternal(args);
|
||||
}
|
||||
|
||||
// release SPs
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
auto statics = m_vStaticListeners;
|
||||
if (!m_vStaticListeners.empty()) {
|
||||
const auto statics = m_vStaticListeners;
|
||||
|
||||
for (auto& l : listeners) {
|
||||
// if there is only one lock, it means the event is only held by the listeners
|
||||
// vector and was removed during our iteration
|
||||
if (l.strongRef() == 1)
|
||||
continue;
|
||||
|
||||
l->emitInternal(args);
|
||||
for (const auto& l : statics) {
|
||||
l->emitInternal(args);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& l : statics) {
|
||||
l->emitInternal(args);
|
||||
}
|
||||
|
||||
// release SPs
|
||||
listeners.clear();
|
||||
|
||||
// we cannot release any expired refs here as one of the listeners could've removed this object and
|
||||
// as such we'd be doing a UAF
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue