summaryrefslogtreecommitdiff
path: root/gtk/gtkobject-support.c
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2002-01-07 10:46:32 +0000
committerJames Henstridge <jamesh@src.gnome.org>2002-01-07 10:46:32 +0000
commit1bc78a422c4127c3d18cf21d1f28a16469d215b9 (patch)
tree3090f188ed51906be9532d6ce19a4b6ab73d6fe9 /gtk/gtkobject-support.c
parent22ddb79502701fc47318ae05e3a7f5e085b9fa68 (diff)
downloadpygtk-1bc78a422c4127c3d18cf21d1f28a16469d215b9.tar.gz
add overriden implementation that allows threads while waiting, so some
2002-01-07 James Henstridge <james@daa.com.au> * gtk/gdk.override (_wrap_gdk_threads_enter): add overriden implementation that allows threads while waiting, so some other thread has a chance to give up the gdk lock. * gtk/gtkmodule.c (functions): remove stuff. * gtk/pygtk-private.h: remove definitions here as well. * gtk/pygtk.h (_PyGtk_FunctionStruct): remove destroy notify and thread block stuff. * gtk/gtkobject-support.c: remove pygtk_destroy_notify. * gtk/gtk.override (pygtk_tree_foreach_marshal): move this function here from gtkobject-support.c, and don't bother blocking threads. (_wrap_gtk_tree_selection_selected_foreach): same here -- don't need to unblock threads. (pygtk_tree_selection_marshal): move this function here from gtkobject-support.c. Convert to use pyg_block_threads. (_wrap_gtk_dialog_run): add overriden implementation that unblocks threads. (_wrap_gtk_main): use pyg_block_threads (_wrap_gtk_main_iteration): same. (_wrap_gtk_item_factory_create_items): same here. (_wrap_gtk_menu_popup): same here. (_wrap_gtk_clist_set_row_data): use pyg_destroy_notify (_wrap_gtk_timeout_add): same here. (_wrap_gtk_idle_add): same here. (_wrap_gtk_quit_add): same here. (_wrap_gtk_input_add_full): same here. (_wrap_gtk_ctree_node_set_row_data): same here. * gtk/gtkobject-support.c: remove PyGTK_BLOCK_THREADS and PyGTK_UNBLOCK_THREADS macros. (pygtk_destroy_notify): use pyg_block_threads. (pygtk_custom_destroy_notify): same. (pygtk_handler_marshal): same. (pygtk_input_marshal): same. * gtk/gdk.override (_wrap_gdk_threads_init): register gdk lock based recursive threads block/unblock functions. If threading was disabled at compile time, then this function will error out. * gtk/gdk.defs (threads_enter, threads_leave, threads_leave): add functions. * gobjectmodule.c (functions): add destroy_notify here as well. * pygobject.h: add destroy_notify to the PyGObject_Functions vtable.
Diffstat (limited to 'gtk/gtkobject-support.c')
-rw-r--r--gtk/gtkobject-support.c151
1 files changed, 8 insertions, 143 deletions
diff --git a/gtk/gtkobject-support.c b/gtk/gtkobject-support.c
index 286d7da6..41571d59 100644
--- a/gtk/gtkobject-support.c
+++ b/gtk/gtkobject-support.c
@@ -5,89 +5,17 @@
#include "pygtk-private.h"
-/* ----------------- Thread stuff -------------------- */
-/* The threading hacks are based on ones supplied by Duncan Grisby
- * of AT&T Labs Cambridge. Since then they have been modified a bit. */
-
-/* The threading code has been enhanced to be a little better with multiple
- * threads accessing GTK+. Here are some notes on the changes by
- * Paul Fisher:
- *
- * If threading is enabled, we create a recursive version of Python's
- * global interpreter mutex using TSD. This scheme makes it possible,
- * although rather hackish, for any thread to make a call into PyGTK,
- * as long as the GDK lock is held (that is, Python code is wrapped
- * around a threads_{enter,leave} pair).
- *
- * A viable alternative would be to wrap each and every GTK call, at
- * the Python/C level, with Py_{BEGIN,END}_ALLOW_THREADS. However,
- * given the nature of Python threading, this option is not
- * particularly appealing.
- */
-
-
-#ifdef ENABLE_PYGTK_THREADING
-static GStaticPrivate pythreadstate_key = G_STATIC_PRIVATE_INIT;
-static GStaticPrivate counter_key = G_STATIC_PRIVATE_INIT;
-
-/* The global Python lock will be grabbed by Python when entering a
- * Python/C function; thus, the initial lock count will always be one.
- */
-# define INITIAL_LOCK_COUNT 1
-# define PyGTK_BLOCK_THREADS \
- { \
- gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key)); \
- if (counter == -INITIAL_LOCK_COUNT) { \
- PyThreadState *_save; \
- _save = g_static_private_get(&pythreadstate_key); \
- Py_BLOCK_THREADS; \
- } \
- counter++; \
- g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL); \
- }
-
-# define PyGTK_UNBLOCK_THREADS \
- { \
- gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key)); \
- counter--; \
- if (counter == -INITIAL_LOCK_COUNT) { \
- PyThreadState *_save; \
- Py_UNBLOCK_THREADS; \
- g_static_private_set(&pythreadstate_key, _save, NULL); \
- } \
- g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL); \
- }
-
-
-#else /* !WITH_THREADS */
-# define PyGTK_BLOCK_THREADS
-# define PyGTK_UNBLOCK_THREADS
-#endif
-
-void pygtk_block_threads(void) { PyGTK_BLOCK_THREADS }
-void pygtk_unblock_threads(void) { PyGTK_UNBLOCK_THREADS }
-
/* ------------------- object support */
void
-pygtk_destroy_notify(gpointer user_data)
-{
- PyObject *obj = (PyObject *)user_data;
-
- PyGTK_BLOCK_THREADS
- Py_DECREF(obj);
- PyGTK_UNBLOCK_THREADS
-}
-
-void
pygtk_custom_destroy_notify(gpointer user_data)
{
PyGtkCustomNotify *cunote = user_data;
- PyGTK_BLOCK_THREADS
+ pyg_block_threads();
Py_XDECREF(cunote->func);
Py_XDECREF(cunote->data);
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
g_free(cunote);
}
@@ -97,7 +25,7 @@ pygtk_handler_marshal(gpointer a, PyObject *func, int nargs, GtkArg *args)
{
PyObject *ret;
- PyGTK_BLOCK_THREADS
+ pyg_block_threads();
if (PyTuple_Check(func))
ret = PyObject_CallObject(PyTuple_GetItem(func, 0),
@@ -108,15 +36,15 @@ pygtk_handler_marshal(gpointer a, PyObject *func, int nargs, GtkArg *args)
PyErr_Print();
PyErr_Clear();
*GTK_RETLOC_BOOL(args[0]) = FALSE;
- PyGTK_UNBLOCK_THREADS
- return;
+ pyg_unblock_threads();
+ return;
}
if (ret == Py_None || (PyInt_Check(ret) && PyInt_AsLong(ret) == 0))
*GTK_RETLOC_BOOL(args[0]) = FALSE;
else
*GTK_RETLOC_BOOL(args[0]) = TRUE;
Py_DECREF(ret);
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
}
/* callback for input handlers */
@@ -125,7 +53,7 @@ pygtk_input_marshal(gpointer a, PyObject *func, int nargs, GtkArg *args)
{
PyObject *tuple, *ret;
- PyGTK_BLOCK_THREADS
+ pyg_block_threads();
tuple = Py_BuildValue("(ii)", GTK_VALUE_INT(args[0]),
GTK_VALUE_FLAGS(args[1]));
ret = PyObject_CallObject(func, tuple);
@@ -135,70 +63,7 @@ pygtk_input_marshal(gpointer a, PyObject *func, int nargs, GtkArg *args)
PyErr_Clear();
} else
Py_DECREF(ret);
- PyGTK_UNBLOCK_THREADS
-}
-
-void
-pygtk_tree_foreach_marshal(GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- PyGtkCustomNotify *cunote = data;
- PyObject *pypath, *retobj;
-
- g_assert(cunote->func);
-
- PyGTK_BLOCK_THREADS
-
- pypath = pygtk_tree_path_to_pyobject(path);
- if (cunote->data)
- retobj = PyEval_CallFunction(cunote->func, "(OO)", pypath,
- cunote->data);
- else
- retobj = PyEval_CallFunction(cunote->func, "(O)", pypath);
- Py_DECREF(pypath);
- Py_XDECREF(retobj);
-
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
}
-gboolean
-pygtk_tree_selection_marshal(GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer data)
-{
- gboolean retval = FALSE;
- PyGtkCustomNotify *cunote = data;
- PyObject *pypath, *retobj;
-
- g_assert(cunote->func);
-
- PyGTK_BLOCK_THREADS
-
- pypath = pygtk_tree_path_to_pyobject(path);
- if (cunote->data)
- retobj = PyEval_CallFunction(cunote->func, "(OO)", pypath,
- cunote->data);
- else
- retobj = PyEval_CallFunction(cunote->func, "(O)", pypath);
- Py_DECREF(pypath);
- if (retobj) {
- if(retobj == Py_None);
- else if(PyInt_Check(retobj))
- retval = PyInt_AsLong(retobj) && TRUE;
- else if(PyLong_Check(retobj))
- retval = PyLong_AsLongLong(retobj) && TRUE;
- else if(PyString_Check(retobj))
- retval = PyString_GET_SIZE(retobj) && TRUE;
-
- Py_DECREF(retobj);
- }
-
- PyGTK_UNBLOCK_THREADS
-
- return retval;
-}