]> www.ginac.de Git - cln.git/commitdiff
Replace CL_REQUIRE/CL_PROVIDE(cl_symbol) with portable code.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Thu, 21 Aug 2008 11:17:50 +0000 (15:17 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Wed, 27 Aug 2008 04:41:03 +0000 (08:41 +0400)
The order of initialization of non-local objects in different compilation units
is not specified in C++. Hence special care should be taken to avoid static
initialization order fiasco. CLN solved the problem with some evil (GCC
specific, and even GCC-version-specific) hack. Replace it with a technique
similar to one used in STL to initialize std::cout and friends.

include/cln/symbol.h
src/base/symbol/cl_symbol.cc

index e4ee0d69d3ff4517ea3805e3b1e8e5967dd03a00..ea59d28e0944e0f056bbb5dd28222bae1724a13d 100644 (file)
@@ -47,8 +47,6 @@ inline bool equal (const cl_symbol& s1, const cl_symbol& s2)
 // Hash code.
 extern unsigned long hashcode (const cl_symbol& s);
 
-CL_REQUIRE(cl_symbol)
-
 }  // namespace cln
 
 #endif /* _CL_SYMBOL_H */
index 7e86b796d16c6a7709e98973ae88df704eea55ca..84d45bdb3873e3acfd41da7d3bc74c7c8e0f470d 100644 (file)
@@ -3,8 +3,6 @@
 // General includes.
 #include "cl_sysdep.h"
 
-CL_PROVIDE(cl_symbol)
-
 // Specification.
 #include "cln/symbol.h"
 
@@ -40,10 +38,6 @@ static void cl_hashtable_from_string_to_symbol_destructor (cl_heap* pointer)
 #endif
 }
 
-cl_class cl_class_hashtable_from_string_to_symbol = {
-       cl_hashtable_from_string_to_symbol_destructor,
-       0
-};
 
 struct cl_ht_from_string_to_symbol : public cl_gcpointer {
        // Constructors.
@@ -64,6 +58,10 @@ struct cl_ht_from_string_to_symbol : public cl_gcpointer {
 
 cl_ht_from_string_to_symbol::cl_ht_from_string_to_symbol ()
 {
+       static const cl_class cl_class_hashtable_from_string_to_symbol = {
+               cl_hashtable_from_string_to_symbol_destructor,
+               0
+       };
        var cl_heap_hashtable_from_string_to_symbol* ht = new cl_heap_hashtable_from_string_to_symbol ();
        ht->refcount = 1;
        ht->type = &cl_class_hashtable_from_string_to_symbol;
@@ -81,11 +79,44 @@ void cl_ht_from_string_to_symbol::put (const cl_string& s) const
 }
 
 // The global symbol table.
-static cl_ht_from_string_to_symbol symbol_table;
+class global_symbol_table
+{
+       static int count;
+       static cl_ht_from_string_to_symbol* symbol_table;
+public:
+       inline cl_symbol* get(const cl_string& s)
+       {
+               return symbol_table->get(s);
+       }
+
+       inline void put(const cl_string& s)
+       {
+               symbol_table->put(s);
+       }
+
+       global_symbol_table();
+       ~global_symbol_table();
+};
+
+int global_symbol_table::count = 0;
+cl_ht_from_string_to_symbol* global_symbol_table::symbol_table;
+
+global_symbol_table::global_symbol_table()
+{
+       if (count++ == 0)
+               symbol_table = new cl_ht_from_string_to_symbol();
+}
+
+global_symbol_table::~global_symbol_table()
+{
+       if (--count == 0)
+               delete symbol_table;
+}
 
 // Create or lookup a symbol from its name.
 cl_symbol::cl_symbol (const cl_string& s)
 {
+       static global_symbol_table symbol_table;
        var cl_symbol * sym_in_table;
        sym_in_table = symbol_table.get(s);
        if (!sym_in_table) {
@@ -101,4 +132,3 @@ cl_symbol::cl_symbol (const cl_string& s)
 
 }  // namespace cln
 
-CL_PROVIDE_END(cl_symbol)