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