diff options
author | Gustavo J. A. M. Carneiro <gcarneiro@src.gnome.org> | 2004-08-04 14:52:52 +0000 |
---|---|---|
committer | Gustavo J. A. M. Carneiro <gcarneiro@src.gnome.org> | 2004-08-04 14:52:52 +0000 |
commit | 272e668c19e45ad9f00312f89077d75bd74646c1 (patch) | |
tree | e0d2de911e9112e2332e9c985ce31b50af04238f | |
parent | e3135078a867a0dcd44647a480d990210e7496c2 (diff) | |
download | pygobject-272e668c19e45ad9f00312f89077d75bd74646c1.tar.gz |
make threading runtime optional
-rw-r--r-- | gobject/gobjectmodule.c | 70 | ||||
-rw-r--r-- | gobject/pygboxed.c | 12 | ||||
-rw-r--r-- | gobject/pygenum.c | 6 | ||||
-rw-r--r-- | gobject/pygflags.c | 6 | ||||
-rw-r--r-- | gobject/pygmaincontext.c | 4 | ||||
-rw-r--r-- | gobject/pygmainloop.c | 4 | ||||
-rw-r--r-- | gobject/pygobject-private.h | 17 | ||||
-rw-r--r-- | gobject/pygobject.c | 24 | ||||
-rw-r--r-- | gobject/pygobject.h | 25 | ||||
-rw-r--r-- | gobject/pygpointer.c | 6 | ||||
-rw-r--r-- | gobject/pygtype.c | 18 |
11 files changed, 122 insertions, 70 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index c45d89b0..546c62b5 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -73,9 +73,9 @@ pyg_destroy_notify(gpointer user_data) PyObject *obj = (PyObject *)user_data; PyGILState_STATE state; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); Py_DECREF(obj); - PyGILState_Release(state); + pyg_gil_state_release(state); } @@ -98,9 +98,9 @@ pyobject_free(gpointer boxed) PyObject *object = boxed; PyGILState_STATE state; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); Py_DECREF(object); - PyGILState_Release(state); + pyg_gil_state_release(state); } @@ -332,12 +332,12 @@ pyg_object_set_property (GObject *object, guint property_id, PyObject *py_pspec, *py_value; PyGILState_STATE state; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); object_wrapper = pygobject_new(object); if (object_wrapper == NULL) { - PyGILState_Release(state); + pyg_gil_state_release(state); return; } @@ -356,7 +356,7 @@ pyg_object_set_property (GObject *object, guint property_id, Py_DECREF(py_pspec); Py_DECREF(py_value); - PyGILState_Release(state); + pyg_gil_state_release(state); } static void @@ -367,12 +367,12 @@ pyg_object_get_property (GObject *object, guint property_id, PyObject *py_pspec; PyGILState_STATE state; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); object_wrapper = pygobject_new(object); if (object_wrapper == NULL) { - PyGILState_Release(state); + pyg_gil_state_release(state); return; } @@ -386,7 +386,7 @@ pyg_object_get_property (GObject *object, guint property_id, Py_DECREF(py_pspec); Py_XDECREF(retval); - PyGILState_Release(state); + pyg_gil_state_release(state); } static void @@ -1257,7 +1257,7 @@ handler_marshal(gpointer user_data) g_return_val_if_fail(user_data != NULL, FALSE); - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); tuple = (PyObject *)user_data; ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0), @@ -1270,7 +1270,7 @@ handler_marshal(gpointer user_data) Py_DECREF(ret); } - PyGILState_Release(state); + pyg_gil_state_release(state); return res; } @@ -1360,7 +1360,7 @@ iowatch_marshal(GIOChannel *source, GIOCondition condition, gpointer user_data) g_return_val_if_fail(user_data != NULL, FALSE); - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); tuple = (PyObject *)user_data; func = PyTuple_GetItem(tuple, 0); @@ -1380,7 +1380,7 @@ iowatch_marshal(GIOChannel *source, GIOCondition condition, gpointer user_data) Py_DECREF(ret); } - PyGILState_Release(state); + pyg_gil_state_release(state); return res; } @@ -1458,6 +1458,31 @@ pyg_main_context_default (PyObject *unused) } +static int +pyg_enable_threads (void) +{ +#ifndef DISABLE_THREADING + PyEval_InitThreads(); + if (!g_threads_got_initialized) + g_thread_init(NULL); + pygobject_api_functions.threads_enabled = TRUE; + return 0; +#else + PyErr_SetString(PyExc_RuntimeError, + "pygtk threading disabled at compile time"); + return -1; +#endif +} + +static PyObject * +pyg_threads_init (PyObject *unused) +{ + if (pyg_enable_threads()) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + static PyMethodDef pygobject_functions[] = { { "type_name", pyg_type_name, METH_VARARGS }, { "type_from_name", pyg_type_from_name, METH_VARARGS }, @@ -1475,6 +1500,7 @@ static PyMethodDef pygobject_functions[] = { { "io_add_watch", (PyCFunction)pyg_io_add_watch, METH_VARARGS|METH_KEYWORDS }, { "source_remove", pyg_source_remove, METH_VARARGS }, { "main_context_default", (PyCFunction)pyg_main_context_default, METH_NOARGS }, + { "threads_init", (PyCFunction)pyg_threads_init, METH_NOARGS }, { NULL, NULL, 0 } }; @@ -1611,7 +1637,7 @@ pyg_error_check(GError **error) PyObject *exc_instance; PyObject *d; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); exc_instance = PyObject_CallFunction(gerror_exc, "z", (*error)->message); @@ -1633,7 +1659,7 @@ pyg_error_check(GError **error) Py_DECREF(exc_instance); g_clear_error(error); - PyGILState_Release(state); + pyg_gil_state_release(state); return TRUE; } @@ -1786,7 +1812,10 @@ struct _PyGObject_Functions pygobject_api_functions = { &PyGFlags_Type, pyg_flags_add, - pyg_flags_from_gtype + pyg_flags_from_gtype, + + FALSE, /* threads_enabled */ + pyg_enable_threads }; #define REGISTER_TYPE(d, type, name) \ @@ -1814,13 +1843,6 @@ initgobject(void) m = Py_InitModule("gobject", pygobject_functions); d = PyModule_GetDict(m); -#ifndef DISABLE_THREADING - PyEval_InitThreads(); - if (!g_threads_got_initialized) - g_thread_init(NULL); -#else - -#endif g_type_init(); PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject", diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c index 05b2c134..cb7636ca 100644 --- a/gobject/pygboxed.c +++ b/gobject/pygboxed.c @@ -30,9 +30,9 @@ static void pyg_boxed_dealloc(PyGBoxed *self) { if (self->free_on_dealloc && self->boxed) { - PyGILState_STATE state = PyGILState_Ensure(); + PyGILState_STATE state = pyg_gil_state_ensure(); g_boxed_free(self->gtype, self->boxed); - PyGILState_Release(state); + pyg_gil_state_release(state); } self->ob_type->tp_free((PyObject *)self); @@ -217,11 +217,11 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, g_return_val_if_fail(boxed_type != 0, NULL); g_return_val_if_fail(!copy_boxed || (copy_boxed && own_ref), NULL); - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); if (!boxed) { Py_INCREF(Py_None); - PyGILState_Release(state); + pyg_gil_state_release(state); return Py_None; } @@ -231,7 +231,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, self = PyObject_NEW(PyGBoxed, tp); if (self == NULL) { - PyGILState_Release(state); + pyg_gil_state_release(state); return NULL; } @@ -241,7 +241,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, self->gtype = boxed_type; self->free_on_dealloc = own_ref; - PyGILState_Release(state); + pyg_gil_state_release(state); return (PyObject *)self; } diff --git a/gobject/pygenum.c b/gobject/pygenum.c index f7a67196..c4c974bf 100644 --- a/gobject/pygenum.c +++ b/gobject/pygenum.c @@ -159,7 +159,7 @@ pyg_enum_add (PyObject * module, g_return_val_if_fail(typename != NULL, NULL); g_return_val_if_fail(g_type_is_a(gtype, G_TYPE_ENUM), NULL); - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); instance_dict = PyDict_New(); stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", @@ -168,7 +168,7 @@ pyg_enum_add (PyObject * module, Py_DECREF(instance_dict); if (!stub) { PyErr_SetString(PyExc_RuntimeError, "can't create const"); - PyGILState_Release(state); + pyg_gil_state_release(state); return NULL; } @@ -216,7 +216,7 @@ pyg_enum_add (PyObject * module, g_type_class_unref(eclass); - PyGILState_Release(state); + pyg_gil_state_release(state); return stub; } diff --git a/gobject/pygflags.c b/gobject/pygflags.c index ca6eec03..381a1dde 100644 --- a/gobject/pygflags.c +++ b/gobject/pygflags.c @@ -195,7 +195,7 @@ pyg_flags_add (PyObject * module, g_return_val_if_fail(typename != NULL, NULL); g_return_val_if_fail(g_type_is_a(gtype, G_TYPE_FLAGS), NULL); - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); instance_dict = PyDict_New(); stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", @@ -204,7 +204,7 @@ pyg_flags_add (PyObject * module, Py_DECREF(instance_dict); if (!stub) { PyErr_SetString(PyExc_RuntimeError, "can't create const"); - PyGILState_Release(state); + pyg_gil_state_release(state); } PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, @@ -246,7 +246,7 @@ pyg_flags_add (PyObject * module, g_type_class_unref(eclass); - PyGILState_Release(state); + pyg_gil_state_release(state); return stub; } diff --git a/gobject/pygmaincontext.c b/gobject/pygmaincontext.c index a3c25f14..64153e37 100644 --- a/gobject/pygmaincontext.c +++ b/gobject/pygmaincontext.c @@ -50,9 +50,9 @@ _wrap_g_main_context_iteration (PyGMainContext *self, PyObject *args) &may_block)) return NULL; - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; ret = g_main_context_iteration(self->context, may_block); - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; return PyBool_FromLong(ret); } diff --git a/gobject/pygmainloop.c b/gobject/pygmainloop.c index 5bd84872..7a6b1c1d 100644 --- a/gobject/pygmainloop.c +++ b/gobject/pygmainloop.c @@ -100,9 +100,9 @@ _wrap_g_main_loop_quit (PyGMainLoop *self) static PyObject * _wrap_g_main_loop_run (PyGMainLoop *self) { - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; g_main_loop_run(self->loop); - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; Py_INCREF(Py_None); return Py_None; diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h index 4ab1a263..770e6925 100644 --- a/gobject/pygobject-private.h +++ b/gobject/pygobject-private.h @@ -19,6 +19,23 @@ extern struct _PyGObject_Functions pygobject_api_functions; (* pygobject_api_functions.unblock_threads)(); \ } G_STMT_END +#define pyg_threads_enabled (pygobject_api_functions.threads_enabled) +#define pyg_gil_state_ensure() (pygobject_api_functions.threads_enabled? (PyGILState_Ensure()) : 0) +#define pyg_gil_state_release(state) G_STMT_START { \ + if (pygobject_api_functions.threads_enabled) \ + PyGILState_Release(state); \ + } G_STMT_END +#define pyg_begin_allow_threads \ + G_STMT_START { \ + PyThreadState *_save = NULL; \ + if (pygobject_api_functions.threads_enabled) \ + _save = PyEval_SaveThread(); +#define pyg_end_allow_threads \ + if (pygobject_api_functions.threads_enabled) \ + PyEval_RestoreThread(_save); \ + } G_STMT_END + + extern GType PY_TYPE_OBJECT; void pyg_destroy_notify (gpointer user_data); diff --git a/gobject/pygobject.c b/gobject/pygobject.c index 9d31ff9f..b5eadc76 100644 --- a/gobject/pygobject.c +++ b/gobject/pygobject.c @@ -247,13 +247,13 @@ pygobject_new_with_interfaces(GType gtype) type_name = g_strconcat(mod_name, ".", gtype_name, NULL); } - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); type = (PyTypeObject*)PyObject_CallFunction((PyObject*)&PyType_Type, "sOO", type_name, bases, dict); g_free(type_name); - PyGILState_Release(state); + pyg_gil_state_release(state); if (type == NULL) { PyErr_Print(); @@ -364,9 +364,9 @@ pygobject_new(GObject *obj) self = PyObject_GC_New(PyGObject, tp); if (self == NULL) return NULL; - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; self->obj = g_object_ref(obj); - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; sink_object(self->obj); self->inst_dict = NULL; @@ -430,9 +430,9 @@ pygobject_dealloc(PyGObject *self) PyObject_GC_UnTrack((PyObject *)self); if (self->obj) { - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; g_object_unref(self->obj); - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; } self->obj = NULL; @@ -441,7 +441,7 @@ pygobject_dealloc(PyGObject *self) } self->inst_dict = NULL; - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; tmp = self->closures; while (tmp) { GClosure *closure = tmp->data; @@ -452,7 +452,7 @@ pygobject_dealloc(PyGObject *self) g_closure_invalidate(closure); } self->closures = NULL; - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; /* the following causes problems with subclassed types */ /* self->ob_type->tp_free((PyObject *)self); */ @@ -525,7 +525,7 @@ pygobject_clear(PyGObject *self) } self->inst_dict = NULL; - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; tmp = self->closures; while (tmp) { GClosure *closure = tmp->data; @@ -535,15 +535,15 @@ pygobject_clear(PyGObject *self) tmp = tmp->next; g_closure_invalidate(closure); } - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; if (self->closures != NULL) g_message("invalidated all closures, but self->closures != NULL !"); if (self->obj) { - Py_BEGIN_ALLOW_THREADS; + pyg_begin_allow_threads; g_object_unref(self->obj); - Py_END_ALLOW_THREADS; + pyg_end_allow_threads; } self->obj = NULL; diff --git a/gobject/pygobject.h b/gobject/pygobject.h index 43ea6641..90d5250b 100644 --- a/gobject/pygobject.h +++ b/gobject/pygobject.h @@ -7,12 +7,6 @@ #include <glib.h> #include <glib-object.h> -#ifdef DISABLE_THREADING -# define PyGILState_STATE int -# define PyGILState_Ensure() (0) -# define PyGILState_Release(x) -#endif - typedef struct { PyObject_HEAD GObject *obj; @@ -138,6 +132,9 @@ struct _PyGObject_Functions { const char *strip_prefix, GType gtype); PyObject* (*flags_from_gtype)(GType gtype, int value); + + gboolean threads_enabled; + int (*enable_threads) (void); }; #ifndef _INSIDE_PYGOBJECT_ @@ -188,6 +185,7 @@ struct _PyGObject_Functions *_PyGObject_API; #define PyGFlags_Type (*_PyGObject_API->flags_type) #define pyg_flags_add (_PyGObject_API->flags_add) #define pyg_flags_from_gtype (_PyGObject_API->flags_from_gtype) +#define pyg_enable_threads (_PyGObject_API->enable_threads) #define pyg_block_threads() G_STMT_START { \ if (_PyGObject_API->block_threads != NULL) \ @@ -198,6 +196,21 @@ struct _PyGObject_Functions *_PyGObject_API; (* _PyGObject_API->unblock_threads)(); \ } G_STMT_END +#define pyg_threads_enabled (_PyGObject_API->threads_enabled) +#define pyg_gil_state_ensure() (_PyGObject_API->threads_enabled? (PyGILState_Ensure()) : 0) +#define pyg_gil_state_release(state) G_STMT_START { \ + if (_PyGObject_API->threads_enabled) \ + PyGILState_Release(state); \ + } G_STMT_END +#define pyg_begin_allow_threads \ + G_STMT_START { \ + PyThreadState *_save = NULL; \ + if (_PyGObject_API->threads_enabled) \ + _save = PyEval_SaveThread(); +#define pyg_end_allow_threads \ + if (_PyGObject_API->threads_enabled) \ + PyEval_RestoreThread(_save); \ + } G_STMT_END #define init_pygobject() { \ PyObject *gobject = PyImport_ImportModule("gobject"); \ diff --git a/gobject/pygpointer.c b/gobject/pygpointer.c index 4173e7cc..c05ece7c 100644 --- a/gobject/pygpointer.c +++ b/gobject/pygpointer.c @@ -190,11 +190,11 @@ pyg_pointer_new(GType pointer_type, gpointer pointer) PyTypeObject *tp; g_return_val_if_fail(pointer_type != 0, NULL); - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); if (!pointer) { Py_INCREF(Py_None); - PyGILState_Release(state); + pyg_gil_state_release(state); return Py_None; } @@ -203,7 +203,7 @@ pyg_pointer_new(GType pointer_type, gpointer pointer) tp = (PyTypeObject *)&PyGPointer_Type; /* fallback */ self = PyObject_NEW(PyGPointer, tp); - PyGILState_Release(state); + pyg_gil_state_release(state); if (self == NULL) return NULL; diff --git a/gobject/pygtype.c b/gobject/pygtype.c index 3a23bb78..b1f3a9b4 100644 --- a/gobject/pygtype.c +++ b/gobject/pygtype.c @@ -723,11 +723,11 @@ pyg_closure_invalidate(gpointer data, GClosure *closure) PyGClosure *pc = (PyGClosure *)closure; PyGILState_STATE state; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); Py_XDECREF(pc->callback); Py_XDECREF(pc->extra_args); Py_XDECREF(pc->swap_data); - PyGILState_Release(state); + pyg_gil_state_release(state); pc->callback = NULL; pc->extra_args = NULL; @@ -747,7 +747,7 @@ pyg_closure_marshal(GClosure *closure, PyObject *params, *ret; guint i; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); @@ -785,7 +785,7 @@ pyg_closure_marshal(GClosure *closure, out: Py_DECREF(params); - PyGILState_Release(state); + pyg_gil_state_release(state); } /** @@ -856,7 +856,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, PyObject *params, *ret; guint i, len; - state = PyGILState_Ensure(); + state = pyg_gil_state_ensure(); g_return_if_fail(invocation_hint != NULL); /* get the object passed as the first argument to the closure */ @@ -882,7 +882,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, if (!method) { PyErr_Clear(); Py_DECREF(object_wrapper); - PyGILState_Release(state); + pyg_gil_state_release(state); return; } Py_DECREF(object_wrapper); @@ -896,7 +896,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, /* error condition */ if (!item) { Py_DECREF(params); - PyGILState_Release(state); + pyg_gil_state_release(state); return; } PyTuple_SetItem(params, i - 1, item); @@ -923,7 +923,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, PyErr_Print(); Py_DECREF(method); Py_DECREF(params); - PyGILState_Release(state); + pyg_gil_state_release(state); return; } Py_DECREF(method); @@ -931,7 +931,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, if (return_value) pyg_value_from_pyobject(return_value, ret); Py_DECREF(ret); - PyGILState_Release(state); + pyg_gil_state_release(state); } /** |