00001 // Filename: globalPointerRegistry.h 00002 // Created by: drose (03Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #ifndef GLOBALPOINTERREGISTRY_H 00020 #define GLOBALPOINTERREGISTRY_H 00021 00022 #include <pandabase.h> 00023 00024 #include "typedObject.h" 00025 00026 #include "pmap.h" 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Class : GlobalPointerRegistry 00030 // Description : This class maintains a one-to-one mapping from 00031 // TypeHandle to a void * pointer. Its purpose is to 00032 // store a pointer to some class data for a given class. 00033 // 00034 // Normally, one would simply use a static data member 00035 // to store class data. However, when the static data 00036 // is associated with a template class, the dynamic 00037 // loader may have difficulty in properly resolving the 00038 // statics. 00039 // 00040 // Consider: class foo<int> defines a static member, _a. 00041 // There should be only one instance of _a shared 00042 // between all instances of foo<int>, and there will be 00043 // a different instance of _a shared between all 00044 // instances of foo<float>. 00045 // 00046 // Now suppose that two different shared libraries 00047 // instantiate foo<int>. In each .so, there exists a 00048 // different foo<int>::_a. It is the loader's job to 00049 // recognize this and collapse them together when both 00050 // libraries are loaded. This usually works, but 00051 // sometimes it doesn't, and you end up with two 00052 // different instances of foo<int>::_a; some functions 00053 // see one instance, while others see the other. We 00054 // have particularly seen this problem occur under Linux 00055 // with gcc. 00056 // 00057 // This class attempts to circumvent the problem by 00058 // managing pointers to data based on TypeHandle. Since 00059 // the TypeHandle will already be unique based on the 00060 // string name supplied to the init_type() function, it 00061 // can be used to differentiate foo<int> from 00062 // foo<float>, while allowing different instances of 00063 // foo<int> to guarantee that they share the same static 00064 // data. 00065 //////////////////////////////////////////////////////////////////// 00066 class EXPCL_PANDA GlobalPointerRegistry { 00067 public: 00068 INLINE static void *get_pointer(TypeHandle type); 00069 INLINE static void store_pointer(TypeHandle type, void *ptr); 00070 INLINE static void clear_pointer(TypeHandle type); 00071 00072 private: 00073 // Nonstatic implementations of the above functions. 00074 void *ns_get_pointer(TypeHandle type) const; 00075 void ns_store_pointer(TypeHandle type, void *ptr); 00076 void ns_clear_pointer(TypeHandle type); 00077 00078 INLINE static GlobalPointerRegistry *get_global_ptr(); 00079 static GlobalPointerRegistry *_global_ptr; 00080 00081 private: 00082 typedef pmap<TypeHandle, void *> Pointers; 00083 Pointers _pointers; 00084 }; 00085 00086 #include "globalPointerRegistry.I" 00087 00088 #endif 00089