Make a copy of the active event handler list before executing them.

This avoids issues if the events being executed add new handlers, since adding a new handler needs to sort the list according to the event priority.

Fixes #8157
This commit is contained in:
Celtic Minstrel 2024-01-14 16:12:14 -05:00 committed by Steve Cotton
parent 91bd96b319
commit 508859cfb6

View file

@ -208,18 +208,14 @@ void manager::execute_on_events(const std::string& event_id, manager::event_func
{
const std::string standardized_event_id = event_handlers::standardize_name(event_id);
const game_data* gd = resources::gamedata;
auto& active_handlers = event_handlers_->get_active();
// Save the end outside the loop so the end point remains constant,
// even if new events are added to the queue.
const unsigned saved_end = active_handlers.size();
// Copy the list so that new events added during processing are not executed.
auto active_handlers = event_handlers_->get_active();
{
// Ensure that event handlers won't be cleaned up while we're iterating them.
event_handler_list_lock lock;
for (unsigned i = 0; i < saved_end; ++i) {
for (unsigned i = 0; i < active_handlers.size(); ++i) {
handler_ptr handler = nullptr;
try {