Fix template replacement cache update crash in RemoveAllGroupsForCompany
This commit is contained in:
@@ -1050,6 +1050,8 @@ Money GetGroupProfitLastYearMinAge(CompanyID company, GroupID id_g, VehicleType
|
|||||||
|
|
||||||
void RemoveAllGroupsForCompany(const CompanyID company)
|
void RemoveAllGroupsForCompany(const CompanyID company)
|
||||||
{
|
{
|
||||||
|
ReindexTemplateReplacementsRecursiveGuard guard;
|
||||||
|
|
||||||
for (Group *g : Group::Iterate()) {
|
for (Group *g : Group::Iterate()) {
|
||||||
if (company == g->owner) {
|
if (company == g->owner) {
|
||||||
DeleteTemplateReplacementsByGroupID(g);
|
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;
|
||||||
robin_hood::unordered_flat_map<GroupID, TemplateID> _template_replacement_index_recursive;
|
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);
|
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)
|
static void MarkTrainsInGroupAsPendingTemplateReplacement(GroupID gid, const TemplateVehicle *tv)
|
||||||
{
|
{
|
||||||
|
if (_template_replacement_index_recursive_guard != 0) return;
|
||||||
|
|
||||||
std::vector<GroupID> groups;
|
std::vector<GroupID> groups;
|
||||||
groups.push_back(gid);
|
groups.push_back(gid);
|
||||||
|
|
||||||
@@ -316,6 +319,11 @@ void ReindexTemplateReplacements()
|
|||||||
|
|
||||||
void ReindexTemplateReplacementsRecursive()
|
void ReindexTemplateReplacementsRecursive()
|
||||||
{
|
{
|
||||||
|
if (_template_replacement_index_recursive_guard != 0) {
|
||||||
|
_template_replacement_index_recursive_guard |= 0x80000000;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_template_replacement_index_recursive.clear();
|
_template_replacement_index_recursive.clear();
|
||||||
for (const Group *group : Group::Iterate()) {
|
for (const Group *group : Group::Iterate()) {
|
||||||
if (group->vehicle_type != VEH_TRAIN) continue;
|
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()
|
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 = std::move(_template_replacement_index);
|
||||||
robin_hood::unordered_flat_map<GroupID, TemplateID> saved_template_replacement_index_recursive = std::move(_template_replacement_index_recursive);
|
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 ReindexTemplateReplacements();
|
||||||
void ReindexTemplateReplacementsRecursive();
|
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 ©src) = 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);
|
int GetTemplateVehicleEstimatedMaxAchievableSpeed(const TemplateVehicle *tv, int mass, const int speed_cap);
|
||||||
|
|
||||||
#endif /* TEMPLATE_VEH_H */
|
#endif /* TEMPLATE_VEH_H */
|
||||||
|
Reference in New Issue
Block a user