summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo J. A. M. Carneiro <gcarneiro@src.gnome.org>2004-08-04 14:52:52 +0000
committerGustavo J. A. M. Carneiro <gcarneiro@src.gnome.org>2004-08-04 14:52:52 +0000
commit272e668c19e45ad9f00312f89077d75bd74646c1 (patch)
treee0d2de911e9112e2332e9c985ce31b50af04238f
parente3135078a867a0dcd44647a480d990210e7496c2 (diff)
downloadpygobject-272e668c19e45ad9f00312f89077d75bd74646c1.tar.gz
pygobject-272e668c19e45ad9f00312f89077d75bd74646c1.tar.xz
pygobject-272e668c19e45ad9f00312f89077d75bd74646c1.zip
make threading runtime optional
-rw-r--r--gobject/gobjectmodule.c70
-rw-r--r--gobject/pygboxed.c12
-rw-r--r--gobject/pygenum.c6
-rw-r--r--gobject/pygflags.c6
-rw-r--r--gobject/pygmaincontext.c4
-rw-r--r--gobject/pygmainloop.c4
-rw-r--r--gobject/pygobject-private.h17
-rw-r--r--gobject/pygobject.c24
-rw-r--r--gobject/pygobject.h25
-rw-r--r--gobject/pygpointer.c6
-rw-r--r--gobject/pygtype.c18
11 files changed, 122 insertions, 70 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index c45d89b..546c62b 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 05b2c13..cb7636c 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 f7a6719..c4c974b 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 ca6eec0..381a1dd 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 a3c25f1..64153e3 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 5bd8487..7a6b1c1 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 4ab1a26..770e692 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 9d31ff9..b5eadc7 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 43ea664..90d5250 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 4173e7c..c05ece7 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 3a23bb7..b1f3a9b 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);
}
/**