diff options
Diffstat (limited to 'gi')
-rw-r--r-- | gi/_glib/pyglib.c | 41 | ||||
-rw-r--r-- | gi/_glib/pyglib.h | 13 | ||||
-rw-r--r-- | gi/_glib/pygoptioncontext.c | 4 | ||||
-rw-r--r-- | gi/_gobject/gobjectmodule.c | 25 | ||||
-rw-r--r-- | gi/_gobject/pygobject-private.h | 33 | ||||
-rw-r--r-- | gi/_gobject/pygobject.c | 33 | ||||
-rw-r--r-- | gi/_gobject/pygobject.h | 48 | ||||
-rw-r--r-- | gi/gimodule.c | 15 | ||||
-rw-r--r-- | gi/pygi-boxed.c | 4 | ||||
-rw-r--r-- | gi/pygi-closure.c | 3 | ||||
-rw-r--r-- | gi/pygi-info.c | 20 | ||||
-rw-r--r-- | gi/pygi-invoke.c | 4 | ||||
-rw-r--r-- | gi/pygi-struct.c | 4 | ||||
-rw-r--r-- | gi/types.py | 12 |
14 files changed, 80 insertions, 179 deletions
diff --git a/gi/_glib/pyglib.c b/gi/_glib/pyglib.c index 54b2d90..9753a52 100644 --- a/gi/_glib/pyglib.c +++ b/gi/_glib/pyglib.c @@ -77,47 +77,6 @@ pyglib_init_internal(PyObject *api) } /** - * pyglib_block_threads: - * - */ -void -pyglib_block_threads(void) -{ - g_return_if_fail (_PyGLib_API != NULL); - - if (_PyGLib_API->block_threads != NULL) - (* _PyGLib_API->block_threads)(); -} - -/** - * pyglib_unblock_threads: - * - */ -void -pyglib_unblock_threads(void) -{ - g_return_if_fail (_PyGLib_API != NULL); - if (_PyGLib_API->unblock_threads != NULL) - (* _PyGLib_API->unblock_threads)(); -} - -/** - * pyglib_set_thread_block_funcs: - * - * hooks to register handlers for getting GDK threads to cooperate - * with python threading - */ -void -pyglib_set_thread_block_funcs (PyGLibThreadBlockFunc block_threads_func, - PyGLibThreadBlockFunc unblock_threads_func) -{ - g_return_if_fail (_PyGLib_API != NULL); - - _PyGLib_API->block_threads = block_threads_func; - _PyGLib_API->unblock_threads = unblock_threads_func; -} - -/** * pyglib_error_marshal: * @error: a pointer to the GError. * diff --git a/gi/_glib/pyglib.h b/gi/_glib/pyglib.h index 0b587b8..1c62f1d 100644 --- a/gi/_glib/pyglib.h +++ b/gi/_glib/pyglib.h @@ -37,24 +37,21 @@ void pyglib_init_internal(PyObject *api); #ifdef DISABLE_THREADING # define pyglib_gil_state_ensure() PyGILState_LOCKED # define pyglib_gil_state_release(state) state -# define pyglib_begin_allow_threads G_STMT_START { -# define pyglib_end_allow_threads } G_STMT_END #else # define pyglib_gil_state_ensure PyGILState_Ensure # define pyglib_gil_state_release PyGILState_Release -# define pyglib_begin_allow_threads Py_BEGIN_ALLOW_THREADS -# define pyglib_end_allow_threads Py_END_ALLOW_THREADS #endif +/* Deprecated, only available for API compatibility. */ +#define pyg_set_thread_block_funcs(a, b) +#define pyglib_block_threads() +#define pyglib_unblock_threads() + gboolean pyglib_error_check(GError **error); PyObject *pyglib_error_marshal (GError **error); gboolean pyglib_gerror_exception_check(GError **error); PyObject *pyglib_register_exception_for_domain(gchar *name, gint error_domain); -void pyglib_set_thread_block_funcs(PyGLibThreadBlockFunc block_threads_func, - PyGLibThreadBlockFunc unblock_threads_func); -void pyglib_block_threads(void); -void pyglib_unblock_threads(void); PyObject * pyglib_option_context_new(GOptionContext *context); PyObject * pyglib_option_group_new(GOptionGroup *group); GOptionGroup * pyglib_option_group_transfer_group(PyObject *self); diff --git a/gi/_glib/pygoptioncontext.c b/gi/_glib/pygoptioncontext.c index b985dbe..8ecbff8 100644 --- a/gi/_glib/pygoptioncontext.c +++ b/gi/_glib/pygoptioncontext.c @@ -130,10 +130,10 @@ pyg_option_context_parse(PyGOptionContext *self, g_assert(argv_length <= G_MAXINT); argv_length_int = argv_length; - pyglib_begin_allow_threads; + Py_BEGIN_ALLOW_THREADS; result = g_option_context_parse(self->context, &argv_length_int, &argv_content, &error); - pyglib_end_allow_threads; + Py_END_ALLOW_THREADS; argv_length = argv_length_int; if (!result) diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c index 3de839d..1e1cbd8 100644 --- a/gi/_gobject/gobjectmodule.c +++ b/gi/_gobject/gobjectmodule.c @@ -48,24 +48,17 @@ static void pyg_flags_add_constants(PyObject *module, GType flags_type, /** * pyg_set_thread_block_funcs: - * @block_threads_func: a function to block Python threads. - * @unblock_threads_func: a function to unblock Python threads. - * - * an interface to allow pygtk to add hooks to handle threading - * similar to the old PyGTK 0.6.x releases. May not work quite right - * anymore. + * Deprecated, only available for ABI compatibility. */ static void -pyg_set_thread_block_funcs (PyGThreadBlockFunc block_threads_func, - PyGThreadBlockFunc unblock_threads_func) +_pyg_set_thread_block_funcs (PyGThreadBlockFunc block_threads_func, + PyGThreadBlockFunc unblock_threads_func) { - g_return_if_fail(pygobject_api_functions.block_threads == NULL && - pygobject_api_functions.unblock_threads == NULL); - - pygobject_api_functions.block_threads = block_threads_func; - pygobject_api_functions.unblock_threads = unblock_threads_func; - pyglib_set_thread_block_funcs(block_threads_func, - unblock_threads_func); + PyGILState_STATE state = pyglib_gil_state_ensure (); + PyErr_Warn (PyExc_DeprecationWarning, + "Using pyg_set_thread_block_funcs is not longer needed. " + "PyGObject always uses Py_BLOCK/UNBLOCK_THREADS."); + pyglib_gil_state_release (state); } /** @@ -2031,7 +2024,7 @@ struct _PyGObject_Functions pygobject_api_functions = { pyg_error_check, - pyg_set_thread_block_funcs, + _pyg_set_thread_block_funcs, (PyGThreadBlockFunc)0, /* block_threads */ (PyGThreadBlockFunc)0, /* unblock_threads */ diff --git a/gi/_gobject/pygobject-private.h b/gi/_gobject/pygobject-private.h index 5de7488..e2a0af7 100644 --- a/gi/_gobject/pygobject-private.h +++ b/gi/_gobject/pygobject-private.h @@ -21,39 +21,6 @@ /* from gobjectmodule.c */ extern struct _PyGObject_Functions pygobject_api_functions; -#define pyg_block_threads() G_STMT_START { \ - if (pygobject_api_functions.block_threads != NULL) \ - (* pygobject_api_functions.block_threads)(); \ - } G_STMT_END -#define pyg_unblock_threads() G_STMT_START { \ - if (pygobject_api_functions.unblock_threads != NULL) \ - (* pygobject_api_functions.unblock_threads)(); \ - } G_STMT_END - -#define pyg_threads_enabled (pygobject_api_functions.threads_enabled) - -#ifdef DISABLE_THREADING -#define pyg_gil_state_ensure() 0 -#define pyg_gil_state_release(state) G_STMT_START { \ - } G_STMT_END - -#else -#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 -#endif - -#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 #ifndef Py_CLEAR /* since Python 2.4 */ diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c index 4ca360a..875da17 100644 --- a/gi/_gobject/pygobject.c +++ b/gi/_gobject/pygobject.c @@ -88,10 +88,9 @@ pygobject_data_free(PyGObjectData *data) if (Py_IsInitialized()) { state = pyglib_gil_state_ensure(); Py_DECREF(data->type); - /* We cannot use pyg_begin_allow_threads here because this is inside + /* We cannot use Py_BEGIN_ALLOW_THREADS here because this is inside * a branch. */ - if (pyg_threads_enabled) - _save = PyEval_SaveThread(); + Py_UNBLOCK_THREADS; /* Modifies _save */ } tmp = closures = data->closures; @@ -114,8 +113,7 @@ pygobject_data_free(PyGObjectData *data) g_free(data); if (Py_IsInitialized()) { - if (pyg_threads_enabled) - PyEval_RestoreThread(_save); + Py_BLOCK_THREADS; /* Restores _save */ pyglib_gil_state_release(state); } } @@ -309,10 +307,11 @@ PyGProps_getattro(PyGProps *self, PyObject *attr) /* The GType is implemented in Python, or we failed to read it via gi: * do a straightforward read. */ + Py_BEGIN_ALLOW_THREADS; g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - pyg_begin_allow_threads; g_object_get_property(self->pygobject->obj, pspec->name, &value); - pyg_end_allow_threads; + Py_END_ALLOW_THREADS; + ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec); g_value_unset(&value); @@ -352,12 +351,11 @@ set_property_from_pspec(GObject *obj, return FALSE; } - pyg_begin_allow_threads; + Py_BEGIN_ALLOW_THREADS; g_object_set_property(obj, pspec->name, &value); - pyg_end_allow_threads; - g_value_unset(&value); - + Py_END_ALLOW_THREADS; + return TRUE; } @@ -1183,9 +1181,9 @@ pygobject_clear(PyGObject *self) g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, self); self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF; } else { - pyg_begin_allow_threads; + Py_BEGIN_ALLOW_THREADS; g_object_unref(self->obj); - pyg_end_allow_threads; + Py_END_ALLOW_THREADS; } self->obj = NULL; } @@ -1320,9 +1318,10 @@ pygobject_get_property(PyGObject *self, PyObject *args) return NULL; } g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - pyg_begin_allow_threads; + Py_BEGIN_ALLOW_THREADS; g_object_get_property(self->obj, param_name, &value); - pyg_end_allow_threads; + Py_END_ALLOW_THREADS; + ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec); g_value_unset(&value); return ret; @@ -1372,9 +1371,9 @@ pygobject_get_properties(PyGObject *self, PyObject *args) } g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - pyg_begin_allow_threads; + Py_BEGIN_ALLOW_THREADS; g_object_get_property(self->obj, property_name, &value); - pyg_end_allow_threads; + Py_END_ALLOW_THREADS; item = pyg_value_as_pyobject(&value, TRUE); PyTuple_SetItem(tuple, i, item); diff --git a/gi/_gobject/pygobject.h b/gi/_gobject/pygobject.h index 3c5e384..f6b531d 100644 --- a/gi/_gobject/pygobject.h +++ b/gi/_gobject/pygobject.h @@ -140,6 +140,7 @@ struct _PyGObject_Functions { PyGThreadBlockFunc unblock_threads_func); PyGThreadBlockFunc block_threads; PyGThreadBlockFunc unblock_threads; + PyTypeObject *paramspec_type; PyObject *(* paramspec_new)(GParamSpec *spec); GParamSpec *(*paramspec_get)(PyObject *tuple); @@ -196,6 +197,28 @@ struct _PyGObject_Functions { PyTypeObject *object_type; }; + +#ifdef DISABLE_THREADING +# define pyg_threads_enabled FALSE +# define pyg_gil_state_ensure() 0 +# define pyg_gil_state_release(state) +# define pyg_begin_allow_threads G_STMT_START { +# define pyg_end_allow_threads } G_STMT_END +#else +# define pyg_threads_enabled TRUE +# define pyg_gil_state_ensure PyGILState_Ensure +# define pyg_gil_state_release PyGILState_Release +# define pyg_begin_allow_threads Py_BEGIN_ALLOW_THREADS +# define pyg_end_allow_threads Py_END_ALLOW_THREADS +#endif + +/* Deprecated, only available for API compatibility. */ +#define pyg_enable_threads() +#define pyg_set_thread_block_funcs(a, b) +#define pyg_block_threads() +#define pyg_unblock_threads() + + #ifndef _INSIDE_PYGOBJECT_ #if defined(NO_IMPORT) || defined(NO_IMPORT_PYGOBJECT) @@ -233,7 +256,6 @@ struct _PyGObject_Functions *_PyGObject_API; #define pyg_flags_add_constants (_PyGObject_API->flags_add_constants) #define pyg_constant_strip_prefix (_PyGObject_API->constant_strip_prefix) #define pyg_error_check (_PyGObject_API->error_check) -#define pyg_set_thread_block_funcs (_PyGObject_API->set_thread_block_funcs) #define PyGParamSpec_Type (*_PyGObject_API->paramspec_type) #define pyg_param_spec_new (_PyGObject_API->paramspec_new) #define pyg_param_spec_from_object (_PyGObject_API->paramspec_get) @@ -247,9 +269,6 @@ 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_gil_state_ensure (_PyGObject_API->gil_state_ensure) -#define pyg_gil_state_release (_PyGObject_API->gil_state_release) #define pyg_register_class_init (_PyGObject_API->register_class_init) #define pyg_register_interface_info (_PyGObject_API->register_interface_info) #define pyg_add_warning_redirection (_PyGObject_API->add_warning_redirection) @@ -257,27 +276,6 @@ struct _PyGObject_Functions *_PyGObject_API; #define pyg_gerror_exception_check (_PyGObject_API->gerror_exception_check) #define pyg_option_group_new (_PyGObject_API->option_group_new) -#define pyg_block_threads() G_STMT_START { \ - if (_PyGObject_API->block_threads != NULL) \ - (* _PyGObject_API->block_threads)(); \ - } G_STMT_END -#define pyg_unblock_threads() G_STMT_START { \ - if (_PyGObject_API->unblock_threads != NULL) \ - (* _PyGObject_API->unblock_threads)(); \ - } G_STMT_END - -#define pyg_threads_enabled (_PyGObject_API->threads_enabled) - -#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 - /** * pygobject_init: diff --git a/gi/gimodule.c b/gi/gimodule.c index 108fc77..5b6bc14 100644 --- a/gi/gimodule.c +++ b/gi/gimodule.c @@ -534,6 +534,7 @@ pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs) gsize total_read = 0; GError* error = NULL; GIOStatus status = G_IO_STATUS_NORMAL; + GIOChannel *iochannel = NULL; if (!PyArg_ParseTuple (args, "Oi:pyg_channel_read", &py_iochannel, &max_count)) { return NULL; @@ -545,7 +546,9 @@ pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs) if (max_count == 0) return PYGLIB_PyBytes_FromString(""); - + + iochannel = pyg_boxed_get (py_iochannel, GIOChannel); + while (status == G_IO_STATUS_NORMAL && (max_count == -1 || total_read < max_count)) { gsize single_read; @@ -572,11 +575,11 @@ pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs) buf = PYGLIB_PyBytes_AsString(ret_obj) + total_read; - pyglib_unblock_threads(); - status = g_io_channel_read_chars(pyg_boxed_get (py_iochannel, GIOChannel), - buf, buf_size, &single_read, &error); - pyglib_block_threads(); - if (pyglib_error_check(&error)) + Py_BEGIN_ALLOW_THREADS; + status = g_io_channel_read_chars (iochannel, buf, buf_size, &single_read, &error); + Py_END_ALLOW_THREADS; + + if (pyglib_error_check(&error)) goto failure; total_read += single_read; diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c index cac2b0d..5bf2c19 100644 --- a/gi/pygi-boxed.c +++ b/gi/pygi-boxed.c @@ -32,10 +32,6 @@ _boxed_dealloc (PyGIBoxed *self) { GType g_type; - PyObject_GC_UnTrack ( (PyObject *) self); - - PyObject_ClearWeakRefs ( (PyObject *) self); - if ( ( (PyGBoxed *) self)->free_on_dealloc) { if (self->slice_allocated) { g_slice_free1 (self->size, ( (PyGBoxed *) self)->boxed); diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c index e70fd86..f30fa52 100644 --- a/gi/pygi-closure.c +++ b/gi/pygi-closure.c @@ -99,6 +99,7 @@ _pygi_closure_assign_pyobj_to_retval (gpointer retval, PyObject *object, } g_base_info_unref (interface_info); + break; } default: *(ffi_arg *) retval = (ffi_arg) arg.v_pointer; @@ -271,7 +272,7 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args) break; } else if (interface_type == GI_INFO_TYPE_ENUM || interface_type == GI_INFO_TYPE_FLAGS) { - g_args[i].v_double = * (double *) args[i]; + g_args[i].v_uint = * (guint *) args[i]; g_base_info_unref (interface); break; } else if (interface_type == GI_INFO_TYPE_STRUCT || diff --git a/gi/pygi-info.c b/gi/pygi-info.c index 1229d78..3e8fcb8 100644 --- a/gi/pygi-info.c +++ b/gi/pygi-info.c @@ -32,9 +32,8 @@ static void _base_info_dealloc (PyGIBaseInfo *self) { - PyObject_GC_UnTrack ( (PyObject *) self); - - PyObject_ClearWeakRefs ( (PyObject *) self); + if (self->inst_weakreflist != NULL) + PyObject_ClearWeakRefs ( (PyObject *) self); g_base_info_unref (self->info); @@ -43,14 +42,6 @@ _base_info_dealloc (PyGIBaseInfo *self) Py_TYPE( (PyObject *) self)->tp_free ( (PyObject *) self); } -static int -_base_info_traverse (PyGIBaseInfo *self, - visitproc visit, - void *arg) -{ - return 0; -} - static PyObject * _base_info_repr (PyGIBaseInfo *self) { @@ -256,6 +247,8 @@ _pygi_info_new (GIBaseInfo *info) } self->info = g_base_info_ref (info); + self->inst_weakreflist = NULL; + self->cache = NULL; return (PyObject *) self; } @@ -1746,10 +1739,7 @@ _pygi_info_register_types (PyObject *m) PyGIBaseInfo_Type.tp_dealloc = (destructor) _base_info_dealloc; PyGIBaseInfo_Type.tp_repr = (reprfunc) _base_info_repr; - PyGIBaseInfo_Type.tp_flags = (Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC); - PyGIBaseInfo_Type.tp_traverse = (traverseproc) _base_info_traverse; + PyGIBaseInfo_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE); PyGIBaseInfo_Type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist); PyGIBaseInfo_Type.tp_methods = _PyGIBaseInfo_methods; PyGIBaseInfo_Type.tp_richcompare = (richcmpfunc)_base_info_richcompare; diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c index 0cbb9ca..ec5da91 100644 --- a/gi/pygi-invoke.c +++ b/gi/pygi-invoke.c @@ -37,7 +37,7 @@ _invoke_callable (PyGIInvokeState *state, error = NULL; - pyg_begin_allow_threads; + Py_BEGIN_ALLOW_THREADS; /* FIXME: use this for now but we can streamline the calls */ if (cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) @@ -68,7 +68,7 @@ _invoke_callable (PyGIInvokeState *state, cache->n_to_py_args, &state->return_arg, &error); - pyg_end_allow_threads; + Py_END_ALLOW_THREADS; if (!retval) { g_assert (error != NULL); diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c index eace77c..29ea38e 100644 --- a/gi/pygi-struct.c +++ b/gi/pygi-struct.c @@ -34,10 +34,6 @@ _struct_dealloc (PyGIStruct *self) (PyObject *) self, &PyGIStructInfo_Type); - PyObject_GC_UnTrack ( (PyObject *) self); - - PyObject_ClearWeakRefs ( (PyObject *) self); - if (info != NULL && g_struct_info_is_foreign ( (GIStructInfo *) info)) { pygi_struct_foreign_release (info, ( (PyGPointer *) self)->pointer); } else if (self->free_on_dealloc) { diff --git a/gi/types.py b/gi/types.py index c44833d..47a81d8 100644 --- a/gi/types.py +++ b/gi/types.py @@ -245,14 +245,16 @@ def find_vfunc_info_in_interface(bases, vfunc_name): # Skip bases without __info__ (static _gobject._gobject.GObject) if base is GInterface or\ not issubclass(base, GInterface) or\ - not hasattr(base, '__info__') or\ - not isinstance(base.__info__, InterfaceInfo): + not hasattr(base, '__info__'): continue - for vfunc in base.__info__.get_vfuncs(): - if vfunc.get_name() == vfunc_name: - return vfunc + # Only look at this classes vfuncs if it is an interface. + if isinstance(base.__info__, InterfaceInfo): + for vfunc in base.__info__.get_vfuncs(): + if vfunc.get_name() == vfunc_name: + return vfunc + # Recurse into the parent classes vfunc = find_vfunc_info_in_interface(base.__bases__, vfunc_name) if vfunc is not None: return vfunc |