thread-safe macro wrappers

This commit is contained in:
David Rose 2009-07-10 17:49:04 +00:00
parent 477c1f3194
commit 3e8b1c6ffd
4 changed files with 227 additions and 11 deletions

View File

@ -41,8 +41,20 @@ 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_get_type_func *P3D_object_get_type;
P3D_object_get_bool_func *P3D_object_get_bool;
P3D_object_get_int_func *P3D_object_get_int;
P3D_object_get_float_func *P3D_object_get_float;
P3D_object_get_string_func *P3D_object_get_string;
P3D_object_get_repr_func *P3D_object_get_repr;
P3D_object_get_property_func *P3D_object_get_property;
P3D_object_set_property_func *P3D_object_set_property;
P3D_object_has_method_func *P3D_object_has_method;
P3D_object_call_func *P3D_object_call;
P3D_object_eval_func *P3D_object_eval;
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;
@ -167,6 +179,17 @@ 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_get_type = (P3D_object_get_type_func *)get_func(module, "P3D_object_get_type");
P3D_object_get_bool = (P3D_object_get_bool_func *)get_func(module, "P3D_object_get_bool");
P3D_object_get_int = (P3D_object_get_int_func *)get_func(module, "P3D_object_get_int");
P3D_object_get_float = (P3D_object_get_float_func *)get_func(module, "P3D_object_get_float");
P3D_object_get_string = (P3D_object_get_string_func *)get_func(module, "P3D_object_get_string");
P3D_object_get_repr = (P3D_object_get_repr_func *)get_func(module, "P3D_object_get_repr");
P3D_object_get_property = (P3D_object_get_property_func *)get_func(module, "P3D_object_get_property");
P3D_object_set_property = (P3D_object_set_property_func *)get_func(module, "P3D_object_set_property");
P3D_object_has_method = (P3D_object_has_method_func *)get_func(module, "P3D_object_has_method");
P3D_object_call = (P3D_object_call_func *)get_func(module, "P3D_object_call");
P3D_object_eval = (P3D_object_eval_func *)get_func(module, "P3D_object_eval");
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");
@ -194,8 +217,20 @@ load_plugin(const string &p3d_plugin_filename) {
P3D_instance_finish == NULL ||
P3D_instance_setup_window == NULL ||
P3D_object_get_type == NULL ||
P3D_object_get_bool == NULL ||
P3D_object_get_int == NULL ||
P3D_object_get_float == NULL ||
P3D_object_get_string == NULL ||
P3D_object_get_repr == NULL ||
P3D_object_get_property == NULL ||
P3D_object_set_property == NULL ||
P3D_object_has_method == NULL ||
P3D_object_call == NULL ||
P3D_object_eval == NULL ||
P3D_object_incref == NULL ||
P3D_object_decref == NULL ||
P3D_make_class_definition == NULL ||
P3D_new_undefined_object == NULL ||
P3D_new_none_object == NULL ||
@ -220,8 +255,20 @@ load_plugin(const string &p3d_plugin_filename) {
<< "\nP3D_instance_finish = " << P3D_instance_finish
<< "\nP3D_instance_setup_window = " << P3D_instance_setup_window
<< "\nP3D_object_get_type = " << P3D_object_get_type
<< "\nP3D_object_get_bool = " << P3D_object_get_bool
<< "\nP3D_object_get_int = " << P3D_object_get_int
<< "\nP3D_object_get_float = " << P3D_object_get_float
<< "\nP3D_object_get_string = " << P3D_object_get_string
<< "\nP3D_object_get_repr = " << P3D_object_get_repr
<< "\nP3D_object_get_property = " << P3D_object_get_property
<< "\nP3D_object_set_property = " << P3D_object_set_property
<< "\nP3D_object_has_method = " << P3D_object_has_method
<< "\nP3D_object_call = " << P3D_object_call
<< "\nP3D_object_eval = " << P3D_object_eval
<< "\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
@ -301,8 +348,20 @@ unload_dso() {
P3D_instance_finish = NULL;
P3D_instance_setup_window = NULL;
P3D_object_get_type = NULL;
P3D_object_get_bool = NULL;
P3D_object_get_int = NULL;
P3D_object_get_float = NULL;
P3D_object_get_string = NULL;
P3D_object_get_repr = NULL;
P3D_object_get_property = NULL;
P3D_object_set_property = NULL;
P3D_object_has_method = NULL;
P3D_object_call = NULL;
P3D_object_eval = NULL;
P3D_object_incref = NULL;
P3D_object_decref = NULL;
P3D_make_class_definition = NULL;
P3D_new_undefined_object = NULL;
P3D_new_none_object = NULL;

View File

@ -27,8 +27,20 @@ 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_get_type_func *P3D_object_get_type;
extern P3D_object_get_bool_func *P3D_object_get_bool;
extern P3D_object_get_int_func *P3D_object_get_int;
extern P3D_object_get_float_func *P3D_object_get_float;
extern P3D_object_get_string_func *P3D_object_get_string;
extern P3D_object_get_repr_func *P3D_object_get_repr;
extern P3D_object_get_property_func *P3D_object_get_property;
extern P3D_object_set_property_func *P3D_object_set_property;
extern P3D_object_has_method_func *P3D_object_has_method;
extern P3D_object_call_func *P3D_object_call;
extern P3D_object_eval_func *P3D_object_eval;
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;

View File

@ -121,6 +121,108 @@ P3D_instance_setup_window(P3D_instance *instance,
RELEASE_LOCK(_api_lock);
}
P3D_object_type
P3D_object_get_type(P3D_object *object) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_object_type result = P3D_OBJECT_GET_TYPE(object);
RELEASE_LOCK(_api_lock);
return result;
}
bool
P3D_object_get_bool(P3D_object *object) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
bool result = P3D_OBJECT_GET_BOOL(object);
RELEASE_LOCK(_api_lock);
return result;
}
int
P3D_object_get_int(P3D_object *object) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
int result = P3D_OBJECT_GET_INT(object);
RELEASE_LOCK(_api_lock);
return result;
}
double
P3D_object_get_float(P3D_object *object) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
double result = P3D_OBJECT_GET_FLOAT(object);
RELEASE_LOCK(_api_lock);
return result;
}
int
P3D_object_get_string(P3D_object *object, char *buffer, int buffer_size) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
int result = P3D_OBJECT_GET_STRING(object, buffer, buffer_size);
RELEASE_LOCK(_api_lock);
return result;
}
int
P3D_object_get_repr(P3D_object *object, char *buffer, int buffer_size) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
int result = P3D_OBJECT_GET_REPR(object, buffer, buffer_size);
RELEASE_LOCK(_api_lock);
return result;
}
P3D_object *
P3D_object_get_property(P3D_object *object, const char *property) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_object *result = P3D_OBJECT_GET_PROPERTY(object, property);
RELEASE_LOCK(_api_lock);
return result;
}
bool
P3D_object_set_property(P3D_object *object, const char *property,
P3D_object *value) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
bool result = P3D_OBJECT_SET_PROPERTY(object, property, value);
RELEASE_LOCK(_api_lock);
return result;
}
bool
P3D_object_has_method(P3D_object *object, const char *method_name) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
bool result = P3D_OBJECT_HAS_METHOD(object, method_name);
RELEASE_LOCK(_api_lock);
return result;
}
P3D_object *
P3D_object_call(P3D_object *object, const char *method_name,
P3D_object *params[], int num_params) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_object *result = P3D_OBJECT_CALL(object, method_name, params, num_params);
RELEASE_LOCK(_api_lock);
return result;
}
P3D_object *
P3D_object_eval(P3D_object *object, const char *expression) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_object *result = P3D_OBJECT_EVAL(object, expression);
RELEASE_LOCK(_api_lock);
return result;
}
void
P3D_object_incref(P3D_object *object) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());

View File

@ -352,14 +352,14 @@ P3D_object_get_float_method(P3D_object *object);
/* Get the object as a string. This method copies the string into the
provided buffer, and returns the actual length of the internal
string (not counting any terminating null character). If the
return value is larger than buffer_length, the string has been
return value is larger than buffer_size, the string has been
truncated. If it is equal, there is no null character written to
the buffer (like strncpy). You may call this method first with
buffer = NULL and buffer_length = 0 to return just the required
buffer = NULL and buffer_size = 0 to return just the required
size of the buffer. */
typedef int
P3D_object_get_string_method(P3D_object *object,
char *buffer, int buffer_length);
char *buffer, int buffer_size);
/* As above, but instead of the literal object data, returns a
user-friendly reprensentation of the object as a string. For
@ -369,7 +369,7 @@ P3D_object_get_string_method(P3D_object *object,
Mechanically, this function works the same way as get_string(). */
typedef int
P3D_object_get_repr_method(P3D_object *object,
char *buffer, int buffer_length);
char *buffer, int buffer_size);
/* Looks up a property on the object by name, i.e. a data member or a
method. The return value is a new-reference P3D_object if the
@ -446,7 +446,12 @@ struct _P3D_object {
};
/* These macros are defined for the convenience of invoking any of the
above method functions on an object. */
above method functions on an object.
CAUTION! None of these macros are thread-safe; you may use them
only in a single-threaded application (or when only a single thread
of the application makes any calls into this API). For thread-safe
variants, see the similarly-named function calls below. */
#define P3D_OBJECT_GET_TYPE(object) ((object)->_class->_get_type((object)))
#define P3D_OBJECT_GET_BOOL(object) ((object)->_class->_get_bool((object)))
@ -458,14 +463,14 @@ struct _P3D_object {
#define P3D_OBJECT_GET_PROPERTY(object, property) ((object)->_class->_get_property((object), (property)))
#define P3D_OBJECT_SET_PROPERTY(object, property, value) ((object)->_class->_set_property((object), (property), (value)))
#define P3D_OBJECT_HAS_METHOD(object, property) ((object)->_class->_has_method((object), (property)))
#define P3D_OBJECT_HAS_METHOD(object, method_name) ((object)->_class->_has_method((object), (method_name)))
#define P3D_OBJECT_CALL(object, method_name, params, num_params) ((object)->_class->_call((object), (method_name), (params), (num_params)))
#define P3D_OBJECT_EVAL(object, expression) ((object)->_class->_eval((object), (expression)))
/* These macros are provided to manipulate the reference count of the
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.
indicated object. As above, these macros are NOT thread-safe. 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
@ -475,8 +480,34 @@ struct _P3D_object {
#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. You may
safely pass a NULL pointer into either; it will be ignored. */
/* Use these functions for thread-safe variants of the above macros. */
typedef P3D_object_type
P3D_object_get_type_func(P3D_object *object);
typedef bool
P3D_object_get_bool_func(P3D_object *object);
typedef int
P3D_object_get_int_func(P3D_object *object);
typedef double
P3D_object_get_float_func(P3D_object *object);
typedef int
P3D_object_get_string_func(P3D_object *object, char *buffer, int buffer_size);
typedef int
P3D_object_get_repr_func(P3D_object *object, char *buffer, int buffer_size);
typedef P3D_object *
P3D_object_get_property_func(P3D_object *object, const char *property);
typedef bool
P3D_object_set_property_func(P3D_object *object, const char *property,
P3D_object *value);
typedef bool
P3D_object_has_method_func(P3D_object *object, const char *method_name);
typedef P3D_object *
P3D_object_call_func(P3D_object *object, const char *method_name,
P3D_object *params[], int num_params);
typedef P3D_object *
P3D_object_eval_func(P3D_object *object, const char *expression);
/* A NULL pointer passed into either incref or decref is safe and will
be quietly ignored. */
typedef void
P3D_object_incref_func(P3D_object *object);
typedef void
@ -761,8 +792,20 @@ 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_get_type_func P3D_object_get_type;
EXPCL_P3D_PLUGIN P3D_object_get_bool_func P3D_object_get_bool;
EXPCL_P3D_PLUGIN P3D_object_get_int_func P3D_object_get_int;
EXPCL_P3D_PLUGIN P3D_object_get_float_func P3D_object_get_float;
EXPCL_P3D_PLUGIN P3D_object_get_string_func P3D_object_get_string;
EXPCL_P3D_PLUGIN P3D_object_get_repr_func P3D_object_get_repr;
EXPCL_P3D_PLUGIN P3D_object_get_property_func P3D_object_get_property;
EXPCL_P3D_PLUGIN P3D_object_set_property_func P3D_object_set_property;
EXPCL_P3D_PLUGIN P3D_object_has_method_func P3D_object_has_method;
EXPCL_P3D_PLUGIN P3D_object_call_func P3D_object_call;
EXPCL_P3D_PLUGIN P3D_object_eval_func P3D_object_eval;
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;