fix un-threadsafe code for creating config enum hashtable.

supermerill/SuperSlicer#997
This commit is contained in:
remi durand 2021-04-28 21:32:47 +02:00
parent 42a0c31cb2
commit f8314609d8
2 changed files with 102 additions and 113 deletions

View File

@ -1444,7 +1444,8 @@ public:
std::string serialize() const override std::string serialize() const override
{ {
const t_config_enum_names& names = ConfigOptionEnum<T>::get_enum_names(); // as names is staic-initialized, it's thread safe
static t_config_enum_names names = ConfigOptionEnum<T>::create_enum_names();
assert(static_cast<int>(this->value) < int(names.size())); assert(static_cast<int>(this->value) < int(names.size()));
return names[static_cast<int>(this->value)]; return names[static_cast<int>(this->value)];
} }
@ -1463,10 +1464,10 @@ public:
return false; return false;
} }
// Map from an enum name to an enum integer value. // Map from an enum name to an enum integer value. Can be used for static initialisation
static const t_config_enum_names& get_enum_names() static t_config_enum_names create_enum_names()
{ {
static t_config_enum_names names; t_config_enum_names names;
if (names.empty()) { if (names.empty()) {
// Initialize the map. // Initialize the map.
const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values(); const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values();

View File

@ -147,161 +147,149 @@ enum ZLiftTop {
}; };
template<> inline const t_config_enum_values& ConfigOptionEnum<CompleteObjectSort>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<CompleteObjectSort>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"object", cosObject},
keys_map["object"] = cosObject; {"lowy", cosY},
keys_map["lowy"] = cosY; {"lowz", cosY},
keys_map["lowz"] = cosY; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"FFF", ptFFF},
keys_map["FFF"] = ptFFF; {"SLA", ptSLA},
keys_map["SLA"] = ptSLA; {"SLS", ptSLS},
keys_map["SLS"] = ptSLS; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<OutputFormat>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<OutputFormat>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"mCWS", ofMaskedCWS},
keys_map["mCWS"] = ofMaskedCWS; {"SL1", ofSL1},
keys_map["SL1"] = ofSL1; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<WipeAlgo>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<WipeAlgo>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"linear", waLinear},
keys_map["linear"] = waLinear; {"quadra", waQuadra},
keys_map["quadra"] = waQuadra; {"expo", waHyper},
keys_map["expo"] = waHyper; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"reprap", gcfRepRap},
keys_map["reprap"] = gcfRepRap; {"repetier", gcfRepetier},
keys_map["repetier"] = gcfRepetier; {"teacup", gcfTeacup},
keys_map["teacup"] = gcfTeacup; {"makerware", gcfMakerWare},
keys_map["makerware"] = gcfMakerWare; {"marlin", gcfMarlin},
keys_map["marlin"] = gcfMarlin; {"lerdge", gcfLerdge},
keys_map["lerdge"] = gcfLerdge; {"klipper", gcfKlipper},
keys_map["klipper"] = gcfKlipper; {"sailfish", gcfSailfish},
keys_map["sailfish"] = gcfSailfish; {"smoothie", gcfSmoothie},
keys_map["smoothie"] = gcfSmoothie; {"sprinter", gcfSprinter},
keys_map["sprinter"] = gcfSprinter; {"mach3", gcfMach3},
keys_map["mach3"] = gcfMach3; {"machinekit", gcfMachinekit},
keys_map["machinekit"] = gcfMachinekit; {"no-extrusion", gcfNoExtrusion},
keys_map["no-extrusion"] = gcfNoExtrusion; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<MachineLimitsUsage>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<MachineLimitsUsage>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"emit_to_gcode", int(MachineLimitsUsage::EmitToGCode)},
keys_map["emit_to_gcode"] = int(MachineLimitsUsage::EmitToGCode); {"time_estimate_only", int(MachineLimitsUsage::TimeEstimateOnly)},
keys_map["time_estimate_only"] = int(MachineLimitsUsage::TimeEstimateOnly); {"limits", int(MachineLimitsUsage::Limits)},
keys_map["limits"] = int(MachineLimitsUsage::Limits); {"ignore", int(MachineLimitsUsage::Ignore)},
keys_map["ignore"] = int(MachineLimitsUsage::Ignore); };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<PrintHostType>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<PrintHostType>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"octoprint", htOctoPrint},
keys_map["octoprint"] = htOctoPrint; {"duet", htDuet},
keys_map["duet"] = htDuet; {"flashair", htFlashAir},
keys_map["flashair"] = htFlashAir; {"astrobox", htAstroBox},
keys_map["astrobox"] = htAstroBox; {"repetier", htRepetier},
keys_map["repetier"] = htRepetier; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<AuthorizationType>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<AuthorizationType>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"key", atKeyPassword},
keys_map["key"] = atKeyPassword; {"user", atUserPassword},
keys_map["user"] = atUserPassword; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"rectilinear", ipRectilinear},
keys_map["rectilinear"] = ipRectilinear; {"monotonic", ipMonotonic},
keys_map["monotonic"] = ipMonotonic; {"grid", ipGrid},
keys_map["grid"] = ipGrid; {"triangles", ipTriangles},
keys_map["triangles"] = ipTriangles; {"stars", ipStars},
keys_map["stars"] = ipStars; {"cubic", ipCubic},
keys_map["cubic"] = ipCubic; {"line", ipLine},
keys_map["line"] = ipLine; {"concentric", ipConcentric},
keys_map["concentric"] = ipConcentric; {"concentricgapfill", ipConcentricGapFill},
keys_map["concentricgapfill"] = ipConcentricGapFill; {"honeycomb", ipHoneycomb},
keys_map["honeycomb"] = ipHoneycomb; {"3dhoneycomb", ip3DHoneycomb},
keys_map["3dhoneycomb"] = ip3DHoneycomb; {"gyroid", ipGyroid},
keys_map["gyroid"] = ipGyroid; {"hilbertcurve", ipHilbertCurve},
keys_map["hilbertcurve"] = ipHilbertCurve; {"archimedeanchords", ipArchimedeanChords},
keys_map["archimedeanchords"] = ipArchimedeanChords; {"octagramspiral", ipOctagramSpiral},
keys_map["octagramspiral"] = ipOctagramSpiral; {"smooth", ipSmooth},
keys_map["smooth"] = ipSmooth; {"smoothtriple", ipSmoothTriple},
keys_map["smoothtriple"] = ipSmoothTriple; {"smoothhilbert", ipSmoothHilbert},
keys_map["smoothhilbert"] = ipSmoothHilbert; {"rectiwithperimeter", ipRectiWithPerimeter},
keys_map["rectiwithperimeter"] = ipRectiWithPerimeter; {"scatteredrectilinear", ipScatteredRectilinear},
keys_map["scatteredrectilinear"]= ipScatteredRectilinear; {"rectilineargapfill", ipRectilinearWGapFill},
keys_map["rectilineargapfill"] = ipRectilinearWGapFill; {"monotonicgapfill", ipMonotonicWGapFill},
keys_map["monotonicgapfill"] = ipMonotonicWGapFill; {"sawtooth", ipSawtooth},
keys_map["sawtooth"] = ipSawtooth; {"adaptivecubic", ipAdaptiveCubic},
keys_map["adaptivecubic"] = ipAdaptiveCubic; {"supportcubic", ipSupportCubic}
keys_map["supportcubic"] = ipSupportCubic; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<IroningType>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<IroningType>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map = {
if (keys_map.empty()) { {"top", int(IroningType::TopSurfaces)},
keys_map["top"] = int(IroningType::TopSurfaces); {"topmost", int(IroningType::TopmostOnly)},
keys_map["topmost"] = int(IroningType::TopmostOnly); {"solid", int(IroningType::AllSolid)},
keys_map["solid"] = int(IroningType::AllSolid); };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map{
if (keys_map.empty()) { {"rectilinear", smpRectilinear},
keys_map["rectilinear"] = smpRectilinear; {"rectilinear-grid", smpRectilinearGrid},
keys_map["rectilinear-grid"] = smpRectilinearGrid; {"honeycomb", smpHoneycomb},
keys_map["honeycomb"] = smpHoneycomb; };
}
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map{
if (keys_map.empty()) { {"random", spRandom},
keys_map["random"] = spRandom; {"nearest", spNearest},
keys_map["nearest"] = spNearest; {"near", spNearest},
keys_map["near"] = spNearest; {"aligned", spAligned},
keys_map["aligned"] = spAligned; {"rear", spRear},
keys_map["rear"] = spRear; {"hidden", spNearest},
keys_map["hidden"] = spNearest; {"custom", spCustom},
keys_map["custom"] = spCustom; };
}
return keys_map; return keys_map;
} }