From f8314609d8e38c7c2562f12d63f0007c72f8d138 Mon Sep 17 00:00:00 2001 From: remi durand Date: Wed, 28 Apr 2021 21:32:47 +0200 Subject: [PATCH] fix un-threadsafe code for creating config enum hashtable. supermerill/SuperSlicer#997 --- src/libslic3r/Config.hpp | 9 +- src/libslic3r/PrintConfig.hpp | 206 ++++++++++++++++------------------ 2 files changed, 102 insertions(+), 113 deletions(-) diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 0b0b785d0..a4c4ee04e 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1444,7 +1444,8 @@ public: std::string serialize() const override { - const t_config_enum_names& names = ConfigOptionEnum::get_enum_names(); + // as names is staic-initialized, it's thread safe + static t_config_enum_names names = ConfigOptionEnum::create_enum_names(); assert(static_cast(this->value) < int(names.size())); return names[static_cast(this->value)]; } @@ -1463,10 +1464,10 @@ public: return false; } - // Map from an enum name to an enum integer value. - static const t_config_enum_names& get_enum_names() + // Map from an enum name to an enum integer value. Can be used for static initialisation + static t_config_enum_names create_enum_names() { - static t_config_enum_names names; + t_config_enum_names names; if (names.empty()) { // Initialize the map. const t_config_enum_values &enum_keys_map = ConfigOptionEnum::get_enum_values(); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 6bb0493e5..14df16792 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -147,161 +147,149 @@ enum ZLiftTop { }; template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["object"] = cosObject; - keys_map["lowy"] = cosY; - keys_map["lowz"] = cosY; - } + static t_config_enum_values keys_map = { + {"object", cosObject}, + {"lowy", cosY}, + {"lowz", cosY}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["FFF"] = ptFFF; - keys_map["SLA"] = ptSLA; - keys_map["SLS"] = ptSLS; - } + static t_config_enum_values keys_map = { + {"FFF", ptFFF}, + {"SLA", ptSLA}, + {"SLS", ptSLS}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["mCWS"] = ofMaskedCWS; - keys_map["SL1"] = ofSL1; - } + static t_config_enum_values keys_map = { + {"mCWS", ofMaskedCWS}, + {"SL1", ofSL1}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["linear"] = waLinear; - keys_map["quadra"] = waQuadra; - keys_map["expo"] = waHyper; - } + static t_config_enum_values keys_map = { + {"linear", waLinear}, + {"quadra", waQuadra}, + {"expo", waHyper}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["reprap"] = gcfRepRap; - keys_map["repetier"] = gcfRepetier; - keys_map["teacup"] = gcfTeacup; - keys_map["makerware"] = gcfMakerWare; - keys_map["marlin"] = gcfMarlin; - keys_map["lerdge"] = gcfLerdge; - keys_map["klipper"] = gcfKlipper; - keys_map["sailfish"] = gcfSailfish; - keys_map["smoothie"] = gcfSmoothie; - keys_map["sprinter"] = gcfSprinter; - keys_map["mach3"] = gcfMach3; - keys_map["machinekit"] = gcfMachinekit; - keys_map["no-extrusion"] = gcfNoExtrusion; - } + static t_config_enum_values keys_map = { + {"reprap", gcfRepRap}, + {"repetier", gcfRepetier}, + {"teacup", gcfTeacup}, + {"makerware", gcfMakerWare}, + {"marlin", gcfMarlin}, + {"lerdge", gcfLerdge}, + {"klipper", gcfKlipper}, + {"sailfish", gcfSailfish}, + {"smoothie", gcfSmoothie}, + {"sprinter", gcfSprinter}, + {"mach3", gcfMach3}, + {"machinekit", gcfMachinekit}, + {"no-extrusion", gcfNoExtrusion}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["emit_to_gcode"] = int(MachineLimitsUsage::EmitToGCode); - keys_map["time_estimate_only"] = int(MachineLimitsUsage::TimeEstimateOnly); - keys_map["limits"] = int(MachineLimitsUsage::Limits); - keys_map["ignore"] = int(MachineLimitsUsage::Ignore); - } + static t_config_enum_values keys_map = { + {"emit_to_gcode", int(MachineLimitsUsage::EmitToGCode)}, + {"time_estimate_only", int(MachineLimitsUsage::TimeEstimateOnly)}, + {"limits", int(MachineLimitsUsage::Limits)}, + {"ignore", int(MachineLimitsUsage::Ignore)}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["octoprint"] = htOctoPrint; - keys_map["duet"] = htDuet; - keys_map["flashair"] = htFlashAir; - keys_map["astrobox"] = htAstroBox; - keys_map["repetier"] = htRepetier; - } + static t_config_enum_values keys_map = { + {"octoprint", htOctoPrint}, + {"duet", htDuet}, + {"flashair", htFlashAir}, + {"astrobox", htAstroBox}, + {"repetier", htRepetier}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["key"] = atKeyPassword; - keys_map["user"] = atUserPassword; - } + static t_config_enum_values keys_map = { + {"key", atKeyPassword}, + {"user", atUserPassword}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["rectilinear"] = ipRectilinear; - keys_map["monotonic"] = ipMonotonic; - keys_map["grid"] = ipGrid; - keys_map["triangles"] = ipTriangles; - keys_map["stars"] = ipStars; - keys_map["cubic"] = ipCubic; - keys_map["line"] = ipLine; - keys_map["concentric"] = ipConcentric; - keys_map["concentricgapfill"] = ipConcentricGapFill; - keys_map["honeycomb"] = ipHoneycomb; - keys_map["3dhoneycomb"] = ip3DHoneycomb; - keys_map["gyroid"] = ipGyroid; - keys_map["hilbertcurve"] = ipHilbertCurve; - keys_map["archimedeanchords"] = ipArchimedeanChords; - keys_map["octagramspiral"] = ipOctagramSpiral; - keys_map["smooth"] = ipSmooth; - keys_map["smoothtriple"] = ipSmoothTriple; - keys_map["smoothhilbert"] = ipSmoothHilbert; - keys_map["rectiwithperimeter"] = ipRectiWithPerimeter; - keys_map["scatteredrectilinear"]= ipScatteredRectilinear; - keys_map["rectilineargapfill"] = ipRectilinearWGapFill; - keys_map["monotonicgapfill"] = ipMonotonicWGapFill; - keys_map["sawtooth"] = ipSawtooth; - keys_map["adaptivecubic"] = ipAdaptiveCubic; - keys_map["supportcubic"] = ipSupportCubic; - } + static t_config_enum_values keys_map = { + {"rectilinear", ipRectilinear}, + {"monotonic", ipMonotonic}, + {"grid", ipGrid}, + {"triangles", ipTriangles}, + {"stars", ipStars}, + {"cubic", ipCubic}, + {"line", ipLine}, + {"concentric", ipConcentric}, + {"concentricgapfill", ipConcentricGapFill}, + {"honeycomb", ipHoneycomb}, + {"3dhoneycomb", ip3DHoneycomb}, + {"gyroid", ipGyroid}, + {"hilbertcurve", ipHilbertCurve}, + {"archimedeanchords", ipArchimedeanChords}, + {"octagramspiral", ipOctagramSpiral}, + {"smooth", ipSmooth}, + {"smoothtriple", ipSmoothTriple}, + {"smoothhilbert", ipSmoothHilbert}, + {"rectiwithperimeter", ipRectiWithPerimeter}, + {"scatteredrectilinear", ipScatteredRectilinear}, + {"rectilineargapfill", ipRectilinearWGapFill}, + {"monotonicgapfill", ipMonotonicWGapFill}, + {"sawtooth", ipSawtooth}, + {"adaptivecubic", ipAdaptiveCubic}, + {"supportcubic", ipSupportCubic} + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["top"] = int(IroningType::TopSurfaces); - keys_map["topmost"] = int(IroningType::TopmostOnly); - keys_map["solid"] = int(IroningType::AllSolid); - } + static t_config_enum_values keys_map = { + {"top", int(IroningType::TopSurfaces)}, + {"topmost", int(IroningType::TopmostOnly)}, + {"solid", int(IroningType::AllSolid)}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["rectilinear"] = smpRectilinear; - keys_map["rectilinear-grid"] = smpRectilinearGrid; - keys_map["honeycomb"] = smpHoneycomb; - } + static t_config_enum_values keys_map{ + {"rectilinear", smpRectilinear}, + {"rectilinear-grid", smpRectilinearGrid}, + {"honeycomb", smpHoneycomb}, + }; return keys_map; } template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["random"] = spRandom; - keys_map["nearest"] = spNearest; - keys_map["near"] = spNearest; - keys_map["aligned"] = spAligned; - keys_map["rear"] = spRear; - keys_map["hidden"] = spNearest; - keys_map["custom"] = spCustom; - } + static t_config_enum_values keys_map{ + {"random", spRandom}, + {"nearest", spNearest}, + {"near", spNearest}, + {"aligned", spAligned}, + {"rear", spRear}, + {"hidden", spNearest}, + {"custom", spCustom}, + }; return keys_map; }