Skip to content

Commit

Permalink
make threading runtime optional
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustavo J. A. M. Carneiro committed Aug 4, 2004
1 parent e313507 commit 272e668
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 70 deletions.
70 changes: 46 additions & 24 deletions gobject/gobjectmodule.c
Expand Up @@ -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);
}


Expand All @@ -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);
}


Expand Down Expand Up @@ -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;
}

Expand All @@ -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
Expand All @@ -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;
}

Expand All @@ -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
Expand Down Expand Up @@ -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),
Expand All @@ -1270,7 +1270,7 @@ handler_marshal(gpointer user_data)
Py_DECREF(ret);
}

PyGILState_Release(state);
pyg_gil_state_release(state);

return res;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 },
Expand All @@ -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 }
};

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) \
Expand Down Expand Up @@ -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",
Expand Down
12 changes: 6 additions & 6 deletions gobject/pygboxed.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions gobject/pygenum.c
Expand Up @@ -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",
Expand All @@ -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;
}

Expand Down Expand Up @@ -216,7 +216,7 @@ pyg_enum_add (PyObject * module,

g_type_class_unref(eclass);

PyGILState_Release(state);
pyg_gil_state_release(state);
return stub;
}

Expand Down
6 changes: 3 additions & 3 deletions gobject/pygflags.c
Expand Up @@ -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",
Expand All @@ -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,
Expand Down Expand Up @@ -246,7 +246,7 @@ pyg_flags_add (PyObject * module,

g_type_class_unref(eclass);

PyGILState_Release(state);
pyg_gil_state_release(state);

return stub;
}
Expand Down
4 changes: 2 additions & 2 deletions gobject/pygmaincontext.c
Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions gobject/pygmainloop.c
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions gobject/pygobject-private.h
Expand Up @@ -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);
Expand Down

0 comments on commit 272e668

Please sign in to comment.