diff options
author | James Henstridge <james@daa.com.au> | 2002-01-07 10:46:32 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 2002-01-07 10:46:32 +0000 |
commit | 1bc78a422c4127c3d18cf21d1f28a16469d215b9 (patch) | |
tree | 3090f188ed51906be9532d6ce19a4b6ab73d6fe9 /gtk/gtkobject-support.c | |
parent | 22ddb79502701fc47318ae05e3a7f5e085b9fa68 (diff) | |
download | pygtk-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.c | 151 |
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; -} |