Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix un-threadsafe code for creating config enum hashtable. #6475

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/libslic3r/Config.hpp
Expand Up @@ -1370,7 +1370,8 @@ class ConfigOptionEnum : public ConfigOptionSingle<T>

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()));
return names[static_cast<int>(this->value)];
}
Expand All @@ -1389,10 +1390,10 @@ class ConfigOptionEnum : public ConfigOptionSingle<T>
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<T>::get_enum_values();
Expand Down
169 changes: 79 additions & 90 deletions src/libslic3r/PrintConfig.hpp
Expand Up @@ -112,144 +112,133 @@ enum BrimType {
};

template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["FFF"] = ptFFF;
keys_map["SLA"] = ptSLA;
}
static t_config_enum_values keys_map = {
{"FFF", ptFFF},
{"SLA", ptSLA},
};
return keys_map;
}

template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["reprap"] = gcfRepRapSprinter;
keys_map["reprapfirmware"] = gcfRepRapFirmware;
keys_map["repetier"] = gcfRepetier;
keys_map["teacup"] = gcfTeacup;
keys_map["makerware"] = gcfMakerWare;
keys_map["marlin"] = gcfMarlinLegacy;
keys_map["marlinfirmware"] = gcfMarlinFirmware;
keys_map["sailfish"] = gcfSailfish;
keys_map["smoothie"] = gcfSmoothie;
keys_map["mach3"] = gcfMach3;
keys_map["machinekit"] = gcfMachinekit;
keys_map["no-extrusion"] = gcfNoExtrusion;
}
static t_config_enum_values keys_map = {
{"reprap", gcfRepRap},
{"reprapfirmware", gcfRepRapFirmware},
{"repetier", gcfRepetier},
{"teacup", gcfTeacup},
{"makerware", gcfMakerWare},
{"marlin", gcfMarlin},
{"marlinfirmware", gcfMarlinFirmware},
{"sailfish", gcfSailfish},
{"smoothie", gcfSmoothie},
{"mach3", gcfMach3},
{"machinekit", gcfMachinekit},
{"no-extrusion", gcfNoExtrusion},
};
return keys_map;
}

template<> inline const t_config_enum_values& ConfigOptionEnum<MachineLimitsUsage>::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["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<PrintHostType>::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<AuthorizationType>::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<FuzzySkinType>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["none"] = int(FuzzySkinType::None);
keys_map["external"] = int(FuzzySkinType::External);
keys_map["all"] = int(FuzzySkinType::All);
static t_config_enum_values keys_map = {
{"none", int(FuzzySkinType::None},
{"external", int(FuzzySkinType::External},
{"all", int(FuzzySkinType::All},
}
return keys_map;
}

template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["rectilinear"] = ipRectilinear;
keys_map["monotonic"] = ipMonotonic;
keys_map["alignedrectilinear"] = ipAlignedRectilinear;
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["honeycomb"] = ipHoneycomb;
keys_map["3dhoneycomb"] = ip3DHoneycomb;
keys_map["gyroid"] = ipGyroid;
keys_map["hilbertcurve"] = ipHilbertCurve;
keys_map["archimedeanchords"] = ipArchimedeanChords;
keys_map["octagramspiral"] = ipOctagramSpiral;
keys_map["adaptivecubic"] = ipAdaptiveCubic;
keys_map["supportcubic"] = ipSupportCubic;
static t_config_enum_values keys_map = {
{"rectilinear", ipRectilinear},
{"monotonic", ipMonotonic},
{"alignedrectilinear", ipAlignedRectilinear},
{"grid", ipGrid},
{"triangles", ipTriangles},
{"stars", ipStars},
{"cubic", ipCubic},
{"line", ipLine},
{"concentric", ipConcentric},
{"honeycomb", ipHoneycomb},
{"3dhoneycomb", ip3DHoneycomb},
{"gyroid", ipGyroid},
{"hilbertcurve", ipHilbertCurve},
{"archimedeanchords", ipArchimedeanChords},
{"octagramspiral", ipOctagramSpiral},
{"adaptivecubic", ipAdaptiveCubic},
{"supportcubic", ipSupportCubic}
}
return keys_map;
}

template<> inline const t_config_enum_values& ConfigOptionEnum<IroningType>::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<SupportMaterialPattern>::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<SupportMaterialStyle>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["grid"] = smsGrid;
keys_map["snug"] = smsSnug;
static t_config_enum_values keys_map{
{"grid", smsGrid},
{"snug", smsSnug},
}
return keys_map;
}

template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["auto"] = smipAuto;
keys_map["rectilinear"] = smipRectilinear;
keys_map["concentric"] = smipConcentric;
static t_config_enum_values keys_map{
{"auto", smipAuto},
{"rectilinear", smipRectilinear},
{"concentric", smipConcentric},
}
return keys_map;
}

template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["random"] = spRandom;
keys_map["nearest"] = spNearest;
keys_map["aligned"] = spAligned;
keys_map["rear"] = spRear;
static t_config_enum_values keys_map{
{"random", spRandom},
{"nearest", spNearest},
{"aligned", spAligned},
{"rear", spRear},
}
return keys_map;
}
Expand Down