From e69ed872a7d6fe3500a109d29446b99de385fc81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20K=C3=B6fferlein?= Date: Sun, 9 Sep 2018 18:31:05 +0200 Subject: [PATCH] Fixed a static initialization race. --- src/gsi/gsi/gsiClassBase.cc | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/gsi/gsi/gsiClassBase.cc b/src/gsi/gsi/gsiClassBase.cc index 4f4b86758..70e2d7f73 100644 --- a/src/gsi/gsi/gsiClassBase.cc +++ b/src/gsi/gsi/gsiClassBase.cc @@ -49,7 +49,8 @@ namespace { // TODO: thread-safe? Unlikely that multiple threads access this member - // we do a initial scan and after this no more write access here. -static std::map s_ti_to_class; +typedef std::map ti_to_class_map_t; +static ti_to_class_map_t *sp_ti_to_class = 0; ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_register) : m_initialized (false), mp_base (0), mp_parent (0), m_doc (doc), m_methods (mm) @@ -63,7 +64,10 @@ ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_registe mp_new_class_collection->push_back (this); // invalidate the "typeinfo to class" map - s_ti_to_class.clear (); + if (sp_ti_to_class) { + delete sp_ti_to_class; + sp_ti_to_class = 0; + } } } @@ -625,7 +629,12 @@ static void add_class_to_map (const gsi::ClassBase *c) if (! ti) { ti = &c->type (); } - if (ti && c->is_of_type (*ti) && !s_ti_to_class.insert (std::make_pair (ti, c)).second) { + + if (! sp_ti_to_class) { + sp_ti_to_class = new ti_to_class_map_t (); + } + + if (ti && c->is_of_type (*ti) && !sp_ti_to_class->insert (std::make_pair (ti, c)).second) { // Duplicate registration of this class tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")"; tl_assert (false); @@ -634,7 +643,7 @@ static void add_class_to_map (const gsi::ClassBase *c) const ClassBase *class_by_typeinfo_no_assert (const std::type_info &ti) { - if (s_ti_to_class.empty ()) { + if (! sp_ti_to_class || sp_ti_to_class->empty ()) { for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { add_class_to_map (c.operator-> ()); } @@ -643,11 +652,15 @@ const ClassBase *class_by_typeinfo_no_assert (const std::type_info &ti) } } - std::map::const_iterator c = s_ti_to_class.find (&ti); - if (c != s_ti_to_class.end ()) { - return c->second; - } else { + if (! sp_ti_to_class) { return 0; + } else { + std::map::const_iterator c = sp_ti_to_class->find (&ti); + if (c != sp_ti_to_class->end ()) { + return c->second; + } else { + return 0; + } } }