86 lines
3.3 KiB
C++
86 lines
3.3 KiB
C++
// Filename: globalPointerRegistry.h
|
|
// Created by: drose (03Feb00)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef GLOBALPOINTERREGISTRY_H
|
|
#define GLOBALPOINTERREGISTRY_H
|
|
|
|
#include "pandabase.h"
|
|
|
|
#include "typedObject.h"
|
|
|
|
#include "pmap.h"
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Class : GlobalPointerRegistry
|
|
// Description : This class maintains a one-to-one mapping from
|
|
// TypeHandle to a void * pointer. Its purpose is to
|
|
// store a pointer to some class data for a given class.
|
|
//
|
|
// Normally, one would simply use a static data member
|
|
// to store class data. However, when the static data
|
|
// is associated with a template class, the dynamic
|
|
// loader may have difficulty in properly resolving the
|
|
// statics.
|
|
//
|
|
// Consider: class foo<int> defines a static member, _a.
|
|
// There should be only one instance of _a shared
|
|
// between all instances of foo<int>, and there will be
|
|
// a different instance of _a shared between all
|
|
// instances of foo<float>.
|
|
//
|
|
// Now suppose that two different shared libraries
|
|
// instantiate foo<int>. In each .so, there exists a
|
|
// different foo<int>::_a. It is the loader's job to
|
|
// recognize this and collapse them together when both
|
|
// libraries are loaded. This usually works, but
|
|
// sometimes it doesn't, and you end up with two
|
|
// different instances of foo<int>::_a; some functions
|
|
// see one instance, while others see the other. We
|
|
// have particularly seen this problem occur under Linux
|
|
// with gcc.
|
|
//
|
|
// This class attempts to circumvent the problem by
|
|
// managing pointers to data based on TypeHandle. Since
|
|
// the TypeHandle will already be unique based on the
|
|
// string name supplied to the init_type() function, it
|
|
// can be used to differentiate foo<int> from
|
|
// foo<float>, while allowing different instances of
|
|
// foo<int> to guarantee that they share the same static
|
|
// data.
|
|
////////////////////////////////////////////////////////////////////
|
|
class EXPCL_PANDA_PUTIL GlobalPointerRegistry {
|
|
public:
|
|
INLINE static void *get_pointer(TypeHandle type);
|
|
INLINE static void store_pointer(TypeHandle type, void *ptr);
|
|
INLINE static void clear_pointer(TypeHandle type);
|
|
|
|
private:
|
|
// Nonstatic implementations of the above functions.
|
|
void *ns_get_pointer(TypeHandle type) const;
|
|
void ns_store_pointer(TypeHandle type, void *ptr);
|
|
void ns_clear_pointer(TypeHandle type);
|
|
|
|
INLINE static GlobalPointerRegistry *get_global_ptr();
|
|
static GlobalPointerRegistry *_global_ptr;
|
|
|
|
private:
|
|
typedef phash_map<TypeHandle, void *> Pointers;
|
|
Pointers _pointers;
|
|
};
|
|
|
|
#include "globalPointerRegistry.I"
|
|
|
|
#endif
|
|
|