From 67afbefaff61817e08faf507f74f1bb8f5206a8a Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 15:17:50 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_symbol) with portable code. 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 | 2 -- src/base/symbol/cl_symbol.cc | 46 +++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/include/cln/symbol.h b/include/cln/symbol.h index e4ee0d6..ea59d28 100644 --- a/include/cln/symbol.h +++ b/include/cln/symbol.h @@ -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 */ diff --git a/src/base/symbol/cl_symbol.cc b/src/base/symbol/cl_symbol.cc index 7e86b79..84d45bd 100644 --- a/src/base/symbol/cl_symbol.cc +++ b/src/base/symbol/cl_symbol.cc @@ -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)