mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
add thread-safe reference count functions
This commit is contained in:
parent
4d2ffd8e77
commit
dc6c73108c
@ -41,6 +41,8 @@ P3D_instance_start_func *P3D_instance_start;
|
||||
P3D_instance_finish_func *P3D_instance_finish;
|
||||
P3D_instance_setup_window_func *P3D_instance_setup_window;
|
||||
|
||||
P3D_object_incref_func *P3D_object_incref;
|
||||
P3D_object_decref_func *P3D_object_decref;
|
||||
P3D_make_class_definition_func *P3D_make_class_definition;
|
||||
P3D_new_undefined_object_func *P3D_new_undefined_object;
|
||||
P3D_new_none_object_func *P3D_new_none_object;
|
||||
@ -165,6 +167,8 @@ load_plugin(const string &p3d_plugin_filename) {
|
||||
P3D_instance_finish = (P3D_instance_finish_func *)get_func(module, "P3D_instance_finish");
|
||||
P3D_instance_setup_window = (P3D_instance_setup_window_func *)get_func(module, "P3D_instance_setup_window");
|
||||
|
||||
P3D_object_incref = (P3D_object_incref_func *)get_func(module, "P3D_object_incref");
|
||||
P3D_object_decref = (P3D_object_decref_func *)get_func(module, "P3D_object_decref");
|
||||
P3D_make_class_definition = (P3D_make_class_definition_func *)get_func(module, "P3D_make_class_definition");
|
||||
P3D_new_undefined_object = (P3D_new_undefined_object_func *)get_func(module, "P3D_new_undefined_object");
|
||||
P3D_new_none_object = (P3D_new_none_object_func *)get_func(module, "P3D_new_none_object");
|
||||
@ -190,6 +194,8 @@ load_plugin(const string &p3d_plugin_filename) {
|
||||
P3D_instance_finish == NULL ||
|
||||
P3D_instance_setup_window == NULL ||
|
||||
|
||||
P3D_object_incref == NULL ||
|
||||
P3D_object_decref == NULL ||
|
||||
P3D_make_class_definition == NULL ||
|
||||
P3D_new_undefined_object == NULL ||
|
||||
P3D_new_none_object == NULL ||
|
||||
@ -214,6 +220,8 @@ load_plugin(const string &p3d_plugin_filename) {
|
||||
<< "\nP3D_instance_finish = " << P3D_instance_finish
|
||||
<< "\nP3D_instance_setup_window = " << P3D_instance_setup_window
|
||||
|
||||
<< "\nP3D_object_incref = " << P3D_object_incref
|
||||
<< "\nP3D_object_decref = " << P3D_object_decref
|
||||
<< "\nP3D_make_class_definition = " << P3D_make_class_definition
|
||||
<< "\nP3D_new_undefined_object = " << P3D_new_undefined_object
|
||||
<< "\nP3D_new_none_object = " << P3D_new_none_object
|
||||
@ -293,6 +301,8 @@ unload_dso() {
|
||||
P3D_instance_finish = NULL;
|
||||
P3D_instance_setup_window = NULL;
|
||||
|
||||
P3D_object_incref = NULL;
|
||||
P3D_object_decref = NULL;
|
||||
P3D_make_class_definition = NULL;
|
||||
P3D_new_undefined_object = NULL;
|
||||
P3D_new_none_object = NULL;
|
||||
|
@ -27,6 +27,8 @@ extern P3D_instance_start_func *P3D_instance_start;
|
||||
extern P3D_instance_finish_func *P3D_instance_finish;
|
||||
extern P3D_instance_setup_window_func *P3D_instance_setup_window;
|
||||
|
||||
extern P3D_object_incref_func *P3D_object_incref;
|
||||
extern P3D_object_decref_func *P3D_object_decref;
|
||||
extern P3D_make_class_definition_func *P3D_make_class_definition;
|
||||
extern P3D_new_undefined_object_func *P3D_new_undefined_object;
|
||||
extern P3D_new_none_object_func *P3D_new_none_object;
|
||||
|
@ -121,6 +121,26 @@ P3D_instance_setup_window(P3D_instance *instance,
|
||||
RELEASE_LOCK(_api_lock);
|
||||
}
|
||||
|
||||
void
|
||||
P3D_object_incref(P3D_object *object) {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
|
||||
P3D_OBJECT_INCREF(object);
|
||||
|
||||
RELEASE_LOCK(_api_lock);
|
||||
}
|
||||
|
||||
void
|
||||
P3D_object_decref(P3D_object *object) {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
|
||||
P3D_OBJECT_DECREF(object);
|
||||
|
||||
RELEASE_LOCK(_api_lock);
|
||||
}
|
||||
|
||||
P3D_class_definition *
|
||||
P3D_make_class_definition() {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
|
@ -307,19 +307,20 @@ typedef enum {
|
||||
P3D_OT_object,
|
||||
} P3D_object_type;
|
||||
|
||||
/* Most methods and functions that return a P3D_object return it with
|
||||
its reference count already incremented by one for the benefit of
|
||||
the caller, leaving the caller the owner of the implicit reference
|
||||
/* Methods and functions that return a P3D_object return it with its
|
||||
reference count already incremented by one for the benefit of the
|
||||
caller, leaving the caller the owner of the implicit reference
|
||||
count. This is referred to as returning a "new reference", using
|
||||
the Python naming convention. Similarly, most methods that receive
|
||||
a P3D_object will implicitly increment the reference count
|
||||
internally if necessary, leaving the caller still the owner of its
|
||||
own reference count. Thus, it is the caller's responsibility to
|
||||
call P3D_OBJECT_DECREF() on any P3D_objects it has received but no
|
||||
the Python naming convention. Similarly, methods that receive a
|
||||
P3D_object as a parameter will generally *not* adjust that object's
|
||||
reference count (except to increment it the object is stored
|
||||
internally), leaving the caller still the owner of the original
|
||||
reference. Thus, it is the caller's responsibility to call
|
||||
P3D_OBJECT_DECREF() on any P3D_objects it has received but no
|
||||
longer wishes to keep. */
|
||||
|
||||
/* This method is called to deallocate the object and all of its
|
||||
internal structures. Do not call it directly; call
|
||||
/* This method is called internally to deallocate the object and all
|
||||
of its internal structures. Do not call it directly; call
|
||||
P3D_OBJECT_DECREF() instead. */
|
||||
typedef void
|
||||
P3D_object_finish_method(P3D_object *object);
|
||||
@ -376,10 +377,13 @@ P3D_object_get_repr_method(P3D_object *object,
|
||||
typedef P3D_object *
|
||||
P3D_object_get_property_method(P3D_object *object, const char *property);
|
||||
|
||||
/* Changes the value at the indicated property. Any existing object
|
||||
already at the corresponding property is deleted. If the value
|
||||
pointer is NULL, the property is deleted. Returns true on success,
|
||||
false on failure. */
|
||||
/* Changes the value at the indicated property. The new value is
|
||||
assigned to the indicating property, and its reference count is
|
||||
correspondingly incremented. Any existing object previously
|
||||
assigned to the corresponding property is replaced, and its
|
||||
reference count decremented. If the value pointer is NULL, the
|
||||
property is removed altogether. Returns true on success, false on
|
||||
failure. */
|
||||
typedef bool
|
||||
P3D_object_set_property_method(P3D_object *object, const char *property,
|
||||
P3D_object *value);
|
||||
@ -405,7 +409,7 @@ P3D_object_call_method(P3D_object *object, const char *method_name,
|
||||
P3D_object *params[], int num_params);
|
||||
|
||||
/* Evaluates an arbitrary JavaScript expression in the context of the
|
||||
object.
|
||||
object. Python objects do not support this method.
|
||||
|
||||
The return value is a new-reference P3D_object on success, or NULL
|
||||
on failure. */
|
||||
@ -459,14 +463,24 @@ struct _P3D_object {
|
||||
#define P3D_OBJECT_EVAL(object, expression) ((object)->_class->_eval((object), (expression)))
|
||||
|
||||
/* These macros are provided to manipulate the reference count of the
|
||||
indicated object. Following Python's convention, XDECREF is
|
||||
provided to decrement the reference count for a pointer that might
|
||||
be NULL (it does nothing in the case of a NULL pointer). */
|
||||
indicated object. They are not thread-safe; they should be called
|
||||
only within the main thread. If you need a thread-safe reference
|
||||
count adjustment, see the similarly-named function calls below.
|
||||
|
||||
Following Python's convention, XDECREF is provided to decrement the
|
||||
reference count for a pointer that might be NULL (it does nothing
|
||||
in the case of a NULL pointer). */
|
||||
|
||||
#define P3D_OBJECT_INCREF(object) (++(object)->_ref_count)
|
||||
#define P3D_OBJECT_DECREF(object) { if (--(object)->_ref_count <= 0) { (object)->_class->_finish((object)); } }
|
||||
#define P3D_OBJECT_XDECREF(object) { if ((object) != (P3D_object *)NULL) { P3D_OBJECT_DECREF(object); } }
|
||||
|
||||
/* Use these functions for thread-safe variants of the above. */
|
||||
typedef void
|
||||
P3D_object_incref_func(P3D_object *object);
|
||||
typedef void
|
||||
P3D_object_decref_func(P3D_object *object);
|
||||
|
||||
|
||||
/* End of method pointer definitions. The following function types
|
||||
are once again meant to define actual function pointers to be found
|
||||
@ -746,6 +760,8 @@ EXPCL_P3D_PLUGIN P3D_instance_start_func P3D_instance_start;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_finish_func P3D_instance_finish;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
|
||||
|
||||
EXPCL_P3D_PLUGIN P3D_object_incref_func P3D_object_incref;
|
||||
EXPCL_P3D_PLUGIN P3D_object_decref_func P3D_object_decref;
|
||||
EXPCL_P3D_PLUGIN P3D_make_class_definition_func P3D_make_class_definition;
|
||||
EXPCL_P3D_PLUGIN P3D_new_undefined_object_func P3D_new_undefined_object;
|
||||
EXPCL_P3D_PLUGIN P3D_new_none_object_func P3D_new_none_object;
|
||||
|
Loading…
x
Reference in New Issue
Block a user