Fix template replacement cache update crash in RemoveAllGroupsForCompany

pull/507/head
Jonathan G Rennison 1 year ago
parent e3e743ba1e
commit d82a050365

@ -1050,6 +1050,8 @@ Money GetGroupProfitLastYearMinAge(CompanyID company, GroupID id_g, VehicleType
void RemoveAllGroupsForCompany(const CompanyID company)
{
ReindexTemplateReplacementsRecursiveGuard guard;
for (Group *g : Group::Iterate()) {
if (company == g->owner) {
DeleteTemplateReplacementsByGroupID(g);

@ -47,6 +47,7 @@ INSTANTIATE_POOL_METHODS(TemplateReplacement)
robin_hood::unordered_flat_map<GroupID, TemplateID> _template_replacement_index;
robin_hood::unordered_flat_map<GroupID, TemplateID> _template_replacement_index_recursive;
static uint32 _template_replacement_index_recursive_guard = 0;
static void MarkTrainsInGroupAsPendingTemplateReplacement(GroupID gid, const TemplateVehicle *tv);
@ -175,6 +176,8 @@ bool ShouldServiceTrainForTemplateReplacement(const Train *t, const TemplateVehi
static void MarkTrainsInGroupAsPendingTemplateReplacement(GroupID gid, const TemplateVehicle *tv)
{
if (_template_replacement_index_recursive_guard != 0) return;
std::vector<GroupID> groups;
groups.push_back(gid);
@ -316,6 +319,11 @@ void ReindexTemplateReplacements()
void ReindexTemplateReplacementsRecursive()
{
if (_template_replacement_index_recursive_guard != 0) {
_template_replacement_index_recursive_guard |= 0x80000000;
return;
}
_template_replacement_index_recursive.clear();
for (const Group *group : Group::Iterate()) {
if (group->vehicle_type != VEH_TRAIN) continue;
@ -333,8 +341,24 @@ void ReindexTemplateReplacementsRecursive()
}
}
ReindexTemplateReplacementsRecursiveGuard::ReindexTemplateReplacementsRecursiveGuard()
{
_template_replacement_index_recursive_guard++;
}
ReindexTemplateReplacementsRecursiveGuard::~ReindexTemplateReplacementsRecursiveGuard()
{
_template_replacement_index_recursive_guard--;
if (_template_replacement_index_recursive_guard == 0x80000000) {
_template_replacement_index_recursive_guard = 0;
ReindexTemplateReplacementsRecursive();
}
}
std::string ValidateTemplateReplacementCaches()
{
assert(_template_replacement_index_recursive_guard == 0);
robin_hood::unordered_flat_map<GroupID, TemplateID> saved_template_replacement_index = std::move(_template_replacement_index);
robin_hood::unordered_flat_map<GroupID, TemplateID> saved_template_replacement_index_recursive = std::move(_template_replacement_index_recursive);

@ -232,6 +232,21 @@ uint DeleteTemplateReplacementsByGroupID(const Group *g);
void ReindexTemplateReplacements();
void ReindexTemplateReplacementsRecursive();
/**
* Guard to inhibit re-indexing of the recursive group to template replacement cache,
* and to disable group-based VF_REPLACEMENT_PENDING changes.
* May be used recursively.
*/
struct ReindexTemplateReplacementsRecursiveGuard {
ReindexTemplateReplacementsRecursiveGuard();
~ReindexTemplateReplacementsRecursiveGuard();
ReindexTemplateReplacementsRecursiveGuard(const ReindexTemplateReplacementsRecursiveGuard &copysrc) = delete;
ReindexTemplateReplacementsRecursiveGuard(ReindexTemplateReplacementsRecursiveGuard &&movesrc) = delete;
ReindexTemplateReplacementsRecursiveGuard &operator=(const ReindexTemplateReplacementsRecursiveGuard &) = delete;
ReindexTemplateReplacementsRecursiveGuard &operator=(ReindexTemplateReplacementsRecursiveGuard &&) = delete;
};
int GetTemplateVehicleEstimatedMaxAchievableSpeed(const TemplateVehicle *tv, int mass, const int speed_cap);
#endif /* TEMPLATE_VEH_H */

Loading…
Cancel
Save