2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2022-09-20 10:59:12 +02:00
|
|
|
|
|
|
|
|
#include "BLI_lazy_threading.hh"
|
2022-11-06 15:04:47 +01:00
|
|
|
#include "BLI_stack.hh"
|
2022-09-20 10:59:12 +02:00
|
|
|
#include "BLI_vector.hh"
|
|
|
|
|
|
|
|
|
|
namespace blender::lazy_threading {
|
|
|
|
|
|
|
|
|
|
/**
|
2022-11-06 15:04:47 +01:00
|
|
|
* This uses a "raw" stack and vector so that it can be destructed after Blender checks for memory
|
|
|
|
|
* leaks. A new list of receivers is created whenever an isolated region is entered to avoid
|
|
|
|
|
* deadlocks.
|
2022-09-20 10:59:12 +02:00
|
|
|
*/
|
2022-11-06 15:04:47 +01:00
|
|
|
using HintReceivers = RawStack<RawVector<FunctionRef<void()>, 0>, 0>;
|
2023-02-10 11:10:31 +11:00
|
|
|
static thread_local HintReceivers hint_receivers = []() {
|
2022-11-06 15:04:47 +01:00
|
|
|
HintReceivers receivers;
|
|
|
|
|
/* Make sure there is always at least one vector. */
|
|
|
|
|
receivers.push_as();
|
|
|
|
|
return receivers;
|
|
|
|
|
}();
|
2022-09-20 10:59:12 +02:00
|
|
|
|
|
|
|
|
void send_hint()
|
|
|
|
|
{
|
2022-11-06 15:04:47 +01:00
|
|
|
for (const FunctionRef<void()> &fn : hint_receivers.peek()) {
|
2022-09-20 10:59:12 +02:00
|
|
|
fn();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HintReceiver::HintReceiver(const FunctionRef<void()> fn)
|
|
|
|
|
{
|
2022-11-06 15:04:47 +01:00
|
|
|
hint_receivers.peek().append(fn);
|
2022-09-20 10:59:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HintReceiver::~HintReceiver()
|
|
|
|
|
{
|
2022-11-06 15:04:47 +01:00
|
|
|
hint_receivers.peek().pop_last();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReceiverIsolation::ReceiverIsolation()
|
|
|
|
|
{
|
|
|
|
|
hint_receivers.push_as();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReceiverIsolation::~ReceiverIsolation()
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(hint_receivers.peek().is_empty());
|
|
|
|
|
hint_receivers.pop();
|
2022-09-20 10:59:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace blender::lazy_threading
|