diff options
author | Johan Dahlin <johan@gnome.org> | 2008-07-20 14:17:04 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-07-20 14:17:04 +0000 |
commit | 45ccf5f6ff1a1805ed326b397c70cf55bba28124 (patch) | |
tree | 59b30668a1b28efced9f417b1e6bc2f4bc9709ec /gobject | |
parent | 9cd866c9066eaa933b54e77225ada672fcfacad3 (diff) | |
download | pygobject-45ccf5f6ff1a1805ed326b397c70cf55bba28124.tar.gz |
Move maincontext and mainloop over to glib. Update the threadstate api to
2008-07-20 Johan Dahlin <johan@gnome.org>
* glib/Makefile.am:
* glib/glibmodule.c (pyglib_main_context_default), (init_glib):
* glib/pyglib.c (pyglib_init), (pyglib_threads_enabled),
(pyglib_main_context_new):
* glib/pyglib.h:
* glib/pygmaincontext.c (_wrap_g_main_context_iteration),
(pyglib_maincontext_register_types):
* glib/pygmaincontext.h:
* glib/pygmainloop.c (pyg_signal_watch_prepare),
(pyg_signal_watch_check), (pyg_main_loop_new),
(_wrap_g_main_loop_get_context), (_wrap_g_main_loop_run),
(pyglib_mainloop_register_types):
* glib/pygmainloop.h:
* gobject/Makefile.am:
* gobject/__init__.py:
* gobject/gobjectmodule.c (pyg_destroy_notify), (pyobject_free),
(pyg_object_set_property), (pyg_object_get_property),
(_pyg_signal_accumulator), (pygobject__g_instance_init),
(pyg_handler_marshal), (pygobject_gil_state_ensure),
(pygobject_gil_state_release), (marshal_emission_hook),
(_log_func), (init_gobject):
* gobject/pygboxed.c (pyg_boxed_dealloc), (pyg_boxed_new):
* gobject/pygenum.c (pyg_enum_add):
* gobject/pygflags.c (pyg_flags_add):
* gobject/pygiochannel.c (pyg_iowatch_marshal):
* gobject/pygmaincontext.c:
* gobject/pygmainloop.c:
* gobject/pygobject-private.h:
* gobject/pygobject.c (pygobject_data_free), (pyg_toggle_notify),
(pygobject_new_with_interfaces), (pygobject_weak_ref_notify):
* gobject/pygobject.h:
* gobject/pygoptiongroup.c (destroy_g_group), (arg_func):
* gobject/pygpointer.c (pyg_pointer_new):
* gobject/pygsource.c (pyg_source_get_context),
(pyg_source_prepare), (pyg_source_check), (pyg_source_dispatch),
(pyg_source_finalize):
* gobject/pygtype.c (pyg_closure_invalidate),
(pyg_closure_marshal), (pyg_signal_class_closure_marshal):
* tests/common.py:
Move maincontext and mainloop over to glib.
Update the threadstate api to use the variant in glib.
svn path=/trunk/; revision=843
Diffstat (limited to 'gobject')
-rw-r--r-- | gobject/Makefile.am | 2 | ||||
-rw-r--r-- | gobject/__init__.py | 3 | ||||
-rw-r--r-- | gobject/gobjectmodule.c | 72 | ||||
-rw-r--r-- | gobject/pygboxed.c | 13 | ||||
-rw-r--r-- | gobject/pygenum.c | 7 | ||||
-rw-r--r-- | gobject/pygflags.c | 7 | ||||
-rw-r--r-- | gobject/pygiochannel.c | 5 | ||||
-rw-r--r-- | gobject/pygmaincontext.c | 144 | ||||
-rw-r--r-- | gobject/pygmainloop.c | 368 | ||||
-rw-r--r-- | gobject/pygobject-private.h | 7 | ||||
-rw-r--r-- | gobject/pygobject.c | 22 | ||||
-rw-r--r-- | gobject/pygobject.h | 12 | ||||
-rw-r--r-- | gobject/pygoptiongroup.c | 11 | ||||
-rw-r--r-- | gobject/pygpointer.c | 7 | ||||
-rw-r--r-- | gobject/pygsource.c | 19 | ||||
-rw-r--r-- | gobject/pygtype.c | 20 |
16 files changed, 101 insertions, 618 deletions
diff --git a/gobject/Makefile.am b/gobject/Makefile.am index f506c3b9..dfd0f508 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -51,8 +51,6 @@ _gobject_la_SOURCES = \ pygobject.c \ pygobject.h \ pygobject-private.h \ - pygmaincontext.c \ - pygmainloop.c \ pygparamspec.c \ pygpointer.c \ pygiochannel.c \ diff --git a/gobject/__init__.py b/gobject/__init__.py index 8eff77ec..19bdd0c2 100644 --- a/gobject/__init__.py +++ b/gobject/__init__.py @@ -31,7 +31,8 @@ from glib import spawn_async, idle_add, timeout_add, timeout_add_seconds, \ io_add_watch, source_remove, child_watch_add, markup_escape_text, \ get_current_time, filename_display_name, filename_display_basename, \ filename_from_utf8, get_application_name, set_application_name, \ - get_prgname, set_prgname, main_depth, Pid, GError, glib_version + get_prgname, set_prgname, main_depth, Pid, GError, glib_version, \ + MainLoop, MainContext, main_context_default from gobject.constants import * from _gobject import * _PyGObject_API = _gobject._PyGObject_API diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index 0a55ce60..5af2c38c 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -100,9 +100,9 @@ pyg_destroy_notify(gpointer user_data) PyObject *obj = (PyObject *)user_data; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); Py_DECREF(obj); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } @@ -125,9 +125,9 @@ pyobject_free(gpointer boxed) PyObject *object = boxed; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); Py_DECREF(object); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } @@ -241,9 +241,6 @@ pyg_lookup_interface_info(GType gtype) return g_type_get_qdata(gtype, pyginterface_info_key); } -/* -------------- GMainContext objects ---------------------------- */ - - /* ---------------- gobject module functions -------------------- */ static PyObject * @@ -405,12 +402,12 @@ pyg_object_set_property (GObject *object, guint property_id, PyObject *py_pspec, *py_value; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); object_wrapper = pygobject_new(object); if (object_wrapper == NULL) { - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return; } @@ -429,7 +426,7 @@ pyg_object_set_property (GObject *object, guint property_id, Py_DECREF(py_pspec); Py_DECREF(py_value); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } static void @@ -440,12 +437,12 @@ pyg_object_get_property (GObject *object, guint property_id, PyObject *py_pspec; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); object_wrapper = pygobject_new(object); if (object_wrapper == NULL) { - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return; } @@ -459,7 +456,7 @@ pyg_object_get_property (GObject *object, guint property_id, Py_DECREF(py_pspec); Py_XDECREF(retval); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } static void @@ -486,7 +483,7 @@ _pyg_signal_accumulator(GSignalInvocationHint *ihint, PyGSignalAccumulatorData *data = _data; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (ihint->detail) py_detail = PyString_FromString(g_quark_to_string(ihint->detail)); else { @@ -520,7 +517,7 @@ _pyg_signal_accumulator(GSignalInvocationHint *ihint, } Py_DECREF(py_retval); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return retval; } @@ -1191,7 +1188,7 @@ pygobject__g_instance_init(GTypeInstance *instance, * g_object_new -> we have no python wrapper, so create it * now */ PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); wrapper = pygobject_new_full(object, FALSE, g_class); args = PyTuple_New(0); kwargs = PyDict_New(); @@ -1199,7 +1196,7 @@ pygobject__g_instance_init(GTypeInstance *instance, PyErr_Print(); Py_DECREF(args); Py_DECREF(kwargs); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } } @@ -1905,7 +1902,7 @@ pyg_handler_marshal(gpointer user_data) g_return_val_if_fail(user_data != NULL, FALSE); - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); tuple = (PyObject *)user_data; ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0), @@ -1918,27 +1915,21 @@ pyg_handler_marshal(gpointer user_data) Py_DECREF(ret); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return res; } -static PyObject * -pyg_main_context_default(PyObject *unused) -{ - return pyg_main_context_new(g_main_context_default()); -} - static int -pyg_gil_state_ensure_py23 (void) +pygobject_gil_state_ensure (void) { - return PyGILState_Ensure(); + return pyglib_gil_state_ensure (); } static void -pyg_gil_state_release_py23 (int flag) +pygobject_gil_state_release (int flag) { - PyGILState_Release(flag); + pyglib_gil_state_release(flag); } static PyObject * @@ -1973,7 +1964,7 @@ marshal_emission_hook(GSignalInvocationHint *ihint, PyObject *params; guint i; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); @@ -2004,7 +1995,7 @@ marshal_emission_hook(GSignalInvocationHint *ihint, retval = (retobj == Py_True ? TRUE : FALSE); Py_XDECREF(retobj); out: - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return retval; } @@ -2128,8 +2119,6 @@ static PyMethodDef pygobject_functions[] = { pyg_object_class_list_properties, METH_VARARGS }, { "new", (PyCFunction)pyg_object_new, METH_VARARGS|METH_KEYWORDS }, - { "main_context_default", - (PyCFunction)pyg_main_context_default, METH_NOARGS }, { "threads_init", (PyCFunction)pyg_threads_init, METH_VARARGS|METH_KEYWORDS }, { "signal_accumulator_true_handled", @@ -2536,9 +2525,9 @@ _log_func(const gchar *log_domain, PyGILState_STATE state; PyObject* warning = user_data; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); PyErr_Warn(warning, (char *) message); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } else g_log_default_handler(log_domain, log_level, message, user_data); } @@ -2649,8 +2638,8 @@ struct _PyGObject_Functions pygobject_api_functions = { FALSE, /* threads_enabled */ pyglib_enable_threads, - pyg_gil_state_ensure_py23, - pyg_gil_state_release_py23, + pygobject_gil_state_ensure, + pygobject_gil_state_release, pyg_register_class_init, pyg_register_interface_info, @@ -2691,6 +2680,7 @@ init_gobject(void) PyObject *m, *d, *o, *tuple, *features; PyObject *descr; PyObject *warning; + PyObject *glib; PyGParamSpec_Type.ob_type = &PyType_Type; if (PyType_Ready(&PyGParamSpec_Type)) @@ -2702,6 +2692,11 @@ init_gobject(void) PyDict_SetItemString(d, "GParamSpec", (PyObject *)&PyGParamSpec_Type); g_type_init(); + pyglib_init(); + + glib = PyImport_ImportModule("glib"); + _PyGMainLoop_Type = (PyTypeObject*)PyObject_GetAttrString(glib, "MainLoop"); + _PyGMainContext_Type = (PyTypeObject*)PyObject_GetAttrString(glib, "MainContext"); pygboxed_type_key = g_quark_from_static_string("PyGBoxed::class"); pygboxed_marshal_key = g_quark_from_static_string("PyGBoxed::marshal"); @@ -2758,9 +2753,6 @@ init_gobject(void) PyGFlags_Type.tp_base = &PyInt_Type; REGISTER_GTYPE(d, PyGFlags_Type, "GFlags", G_TYPE_FLAGS); - REGISTER_TYPE(d, PyGMainLoop_Type, "MainLoop"); - REGISTER_TYPE(d, PyGMainContext_Type, "MainContext"); - REGISTER_TYPE(d, PyGIOChannel_Type, "IOChannel"); REGISTER_TYPE(d, PyGSource_Type, "Source"); diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c index 93c86add..01217bb9 100644 --- a/gobject/pygboxed.c +++ b/gobject/pygboxed.c @@ -24,15 +24,16 @@ # include <config.h> #endif +#include <pyglib.h> #include "pygobject-private.h" static void pyg_boxed_dealloc(PyGBoxed *self) { if (self->free_on_dealloc && self->boxed) { - PyGILState_STATE state = pyg_gil_state_ensure(); + PyGILState_STATE state = pyglib_gil_state_ensure(); g_boxed_free(self->gtype, self->boxed); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } self->ob_type->tp_free((PyObject *)self); @@ -213,11 +214,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 = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (!boxed) { Py_INCREF(Py_None); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return Py_None; } @@ -227,7 +228,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, self = PyObject_NEW(PyGBoxed, tp); if (self == NULL) { - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return NULL; } @@ -237,7 +238,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, self->gtype = boxed_type; self->free_on_dealloc = own_ref; - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return (PyObject *)self; } diff --git a/gobject/pygenum.c b/gobject/pygenum.c index 7de2b3b6..28bdf70f 100644 --- a/gobject/pygenum.c +++ b/gobject/pygenum.c @@ -25,6 +25,7 @@ # include <config.h> #endif +#include <pyglib.h> #include "pygobject-private.h" static PyObject * @@ -190,7 +191,7 @@ pyg_enum_add (PyObject * module, return NULL; } - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); instance_dict = PyDict_New(); stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", @@ -199,7 +200,7 @@ pyg_enum_add (PyObject * module, Py_DECREF(instance_dict); if (!stub) { PyErr_SetString(PyExc_RuntimeError, "can't create const"); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return NULL; } @@ -255,7 +256,7 @@ pyg_enum_add (PyObject * module, g_type_class_unref(eclass); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return stub; } diff --git a/gobject/pygflags.c b/gobject/pygflags.c index 4f028b9d..2ce21744 100644 --- a/gobject/pygflags.c +++ b/gobject/pygflags.c @@ -25,6 +25,7 @@ # include <config.h> #endif +#include <pyglib.h> #include "pygobject-private.h" #define GET_INT_VALUE(x) (((PyIntObject*)x)->ob_ival) @@ -212,7 +213,7 @@ pyg_flags_add (PyObject * module, return NULL; } - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); instance_dict = PyDict_New(); stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", @@ -221,7 +222,7 @@ pyg_flags_add (PyObject * module, Py_DECREF(instance_dict); if (!stub) { PyErr_SetString(PyExc_RuntimeError, "can't create const"); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return NULL; } @@ -275,7 +276,7 @@ pyg_flags_add (PyObject * module, g_type_class_unref(eclass); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return stub; } diff --git a/gobject/pygiochannel.c b/gobject/pygiochannel.c index a7f3629c..34ef8371 100644 --- a/gobject/pygiochannel.c +++ b/gobject/pygiochannel.c @@ -4,6 +4,7 @@ # include <config.h> #endif +#include <pyglib.h> #include "pygobject-private.h" #include "pythread.h" #include <structmember.h> /* for PyMemberDef */ @@ -441,7 +442,7 @@ pyg_iowatch_marshal(GIOChannel *source, g_return_val_if_fail(((PyGIOChannel *) data->iochannel)->channel == source, FALSE); - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (data->user_data) ret = PyObject_CallFunction(data->callback, "OiO", data->iochannel, @@ -457,7 +458,7 @@ pyg_iowatch_marshal(GIOChannel *source, res = PyObject_IsTrue(ret); Py_DECREF(ret); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return res; } diff --git a/gobject/pygmaincontext.c b/gobject/pygmaincontext.c deleted file mode 100644 index b320eea7..00000000 --- a/gobject/pygmaincontext.c +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * - * pygmaincontext.c: GMainContext wrapper - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "pygobject-private.h" - -static int -pyg_main_context_init(PyGMainContext *self) -{ - self->context = g_main_context_new(); - return 0; -} - -static void -pyg_main_context_dealloc(PyGMainContext *self) -{ - if (self->context != NULL) { - g_main_context_unref(self->context); - self->context = NULL; - } - - PyObject_Del(self); -} - -static int -pyg_main_context_compare(PyGMainContext *self, PyGMainContext *v) -{ - if (self->context == v->context) return 0; - if (self->context > v->context) return -1; - return 1; -} - -static PyObject * -_wrap_g_main_context_iteration (PyGMainContext *self, PyObject *args) -{ - gboolean ret, may_block = TRUE; - - if (!PyArg_ParseTuple(args, "|i:GMainContext.iteration", - &may_block)) - return NULL; - - pyg_begin_allow_threads; - ret = g_main_context_iteration(self->context, may_block); - pyg_end_allow_threads; - - return PyBool_FromLong(ret); -} - -static PyObject * -_wrap_g_main_context_pending (PyGMainContext *self) -{ - return PyBool_FromLong(g_main_context_pending(self->context)); -} - -static PyMethodDef _PyGMainContext_methods[] = { - { "iteration", (PyCFunction)_wrap_g_main_context_iteration, METH_VARARGS }, - { "pending", (PyCFunction)_wrap_g_main_context_pending, METH_NOARGS }, - { NULL, NULL, 0 } -}; - -PyTypeObject PyGMainContext_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "gobject.MainContext", - sizeof(PyGMainContext), - 0, - /* methods */ - (destructor)pyg_main_context_dealloc, - (printfunc)0, - (getattrfunc)0, - (setattrfunc)0, - (cmpfunc)pyg_main_context_compare, - (reprfunc)0, - 0, - 0, - 0, - (hashfunc)0, - (ternaryfunc)0, - (reprfunc)0, - (getattrofunc)0, - (setattrofunc)0, - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - NULL, - (traverseproc)0, - (inquiry)0, - (richcmpfunc)0, - 0, - (getiterfunc)0, - (iternextfunc)0, - _PyGMainContext_methods, - 0, - 0, - NULL, - NULL, - (descrgetfunc)0, - (descrsetfunc)0, - 0, - (initproc)pyg_main_context_init, -}; - -/** - * pyg_main_context_new: - * @context: a GMainContext. - * - * Creates a wrapper for a GMainContext. - * - * Returns: the GMainContext wrapper. - */ -PyObject * -pyg_main_context_new(GMainContext *context) -{ - PyGMainContext *self; - - self = (PyGMainContext *)PyObject_NEW(PyGMainContext, - &PyGMainContext_Type); - if (self == NULL) - return NULL; - - self->context = g_main_context_ref(context); - return (PyObject *)self; -} diff --git a/gobject/pygmainloop.c b/gobject/pygmainloop.c deleted file mode 100644 index c80c41fe..00000000 --- a/gobject/pygmainloop.c +++ /dev/null @@ -1,368 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * Copyright (C) 2004 Johan Dahlin - * - * pygmainloop.c: GMainLoop wrapper - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "pygobject-private.h" -#include "pythread.h" - -#ifdef DISABLE_THREADING -static GMainLoop *pyg_current_main_loop = NULL;; - -static inline GMainLoop * -pyg_save_current_main_loop (GMainLoop *main_loop) -{ - GMainLoop *retval = pyg_current_main_loop; - - g_return_val_if_fail(main_loop != NULL, NULL); - - pyg_current_main_loop = g_main_loop_ref(main_loop); - - return retval; -} - -static inline void -pyg_restore_current_main_loop (GMainLoop *main_loop) -{ - if (pyg_current_main_loop != NULL) - g_main_loop_unref(pyg_current_main_loop); - pyg_current_main_loop = main_loop; -} - -static inline GMainLoop * -pyg_get_current_main_loop (void) -{ - return pyg_current_main_loop; -} -#else /* !defined(#ifndef DISABLE_THREADING) */ - -static int pyg_current_main_loop_key = -1; - -static inline GMainLoop * -pyg_save_current_main_loop (GMainLoop *main_loop) -{ - GMainLoop *retval; - - g_return_val_if_fail(main_loop != NULL, NULL); - - if (pyg_current_main_loop_key == -1) - pyg_current_main_loop_key = PyThread_create_key(); - - retval = PyThread_get_key_value(pyg_current_main_loop_key); - PyThread_delete_key_value(pyg_current_main_loop_key); - PyThread_set_key_value(pyg_current_main_loop_key, - g_main_loop_ref(main_loop)); - - return retval; -} - -static inline void -pyg_restore_current_main_loop (GMainLoop *main_loop) -{ - GMainLoop *prev; - - g_return_if_fail (pyg_current_main_loop_key != -1); - - prev = PyThread_get_key_value(pyg_current_main_loop_key); - if (prev != NULL) - g_main_loop_unref(prev); - PyThread_delete_key_value(pyg_current_main_loop_key); - if (main_loop != NULL) - PyThread_set_key_value(pyg_current_main_loop_key, main_loop); -} - -static inline GMainLoop * -pyg_get_current_main_loop (void) -{ - if (pyg_current_main_loop_key == -1) - return NULL; - return PyThread_get_key_value(pyg_current_main_loop_key); -} -#endif /* DISABLE_THREADING */ - -typedef struct { - GSource source; - int fds[2]; - GPollFD fd; -} PySignalWatchSource; - -static gboolean -pyg_signal_watch_prepare(GSource *source, - int *timeout) -{ - PySignalWatchSource *real_source = (PySignalWatchSource *)source; - - /* Python only invokes signal handlers from the main thread, - * so if a thread other than the main thread receives the signal - * from the kernel, PyErr_CheckSignals() from that thread will - * do nothing. - */ - - /* On Windows g_poll() won't be interrupted by a signal - * (AFAIK), so we need the timeout there too, even if there's - * only one thread. - */ -#ifndef PLATFORM_WIN32 - if (!pyg_threads_enabled) - return FALSE; -#endif - -#ifdef HAVE_PYSIGNAL_SETWAKEUPFD - if (real_source->fds[0] != 0) - return FALSE; - - /* Unfortunately we need to create a new pipe here instead of - * reusing the pipe inside the GMainContext. - * Ideally an api should be added to GMainContext which allows us - * to reuse that pipe which would suit us perfectly fine. - */ - if (pipe(real_source->fds) < 0) - g_error("Cannot create main loop pipe: %s\n", - g_strerror(errno)); - - real_source->fd.fd = real_source->fds[0]; - real_source->fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR; - g_source_add_poll(source, &real_source->fd); - - PySignal_SetWakeupFd(real_source->fds[1]); - -#else /* !HAVE_PYSIGNAL_SETWAKEUPFD */ - /* If we're using 2.5 or an earlier version of python we - * will default to a timeout every second, be aware, - * this will cause unnecessary wakeups, see - * http://bugzilla.gnome.org/show_bug.cgi?id=481569 - */ - *timeout = 1000; -#endif /* HAVE_PYSIGNAL_SETWAKEUPFD */ - - return FALSE; -} - -static gboolean -pyg_signal_watch_check(GSource *source) -{ - PyGILState_STATE state; - GMainLoop *main_loop; - - state = pyg_gil_state_ensure(); - - main_loop = pyg_get_current_main_loop(); - - if (PyErr_CheckSignals() == -1 && main_loop != NULL) { - PyErr_SetNone(PyExc_KeyboardInterrupt); - g_main_loop_quit(main_loop); - } - - pyg_gil_state_release(state); - - return FALSE; -} - -static gboolean -pyg_signal_watch_dispatch(GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - /* We should never be dispatched */ - g_assert_not_reached(); - return TRUE; -} - -static void -pyg_signal_watch_finalize(GSource *source) -{ - PySignalWatchSource *real_source = (PySignalWatchSource*)source; - - if (source != NULL) { - if (real_source->fds[0] != 0) - close(real_source->fds[0]); - - if (real_source->fds[1] != 0) - close(real_source->fds[1]); - } -} - -static GSourceFuncs pyg_signal_watch_funcs = -{ - pyg_signal_watch_prepare, - pyg_signal_watch_check, - pyg_signal_watch_dispatch, - pyg_signal_watch_finalize -}; - -static GSource * -pyg_signal_watch_new(void) -{ - return g_source_new(&pyg_signal_watch_funcs, sizeof(PySignalWatchSource)); -} - -static int -pyg_main_loop_new(PyGMainLoop *self, PyObject *args, PyObject *kwargs) -{ - - static char *kwlist[] = { "context", "is_running", NULL }; - PyObject *py_context = Py_None; - int is_running; - GMainContext *context; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Ob:GMainLoop.__init__", - kwlist, &py_context, &is_running)) - return -1; - - if (!PyObject_TypeCheck(py_context, &PyGMainContext_Type) && - py_context != Py_None) { - PyErr_SetString(PyExc_TypeError, - "context must be a gobject.GMainContext or None"); - return -1; - } - - if (py_context != Py_None) { - context = ((PyGMainContext*)py_context)->context; - } else { - context = NULL; - } - - self->loop = g_main_loop_new(context, is_running); - - self->signal_source = pyg_signal_watch_new(); - g_source_attach(self->signal_source, context); - - return 0; -} - -static void -pyg_main_loop_dealloc(PyGMainLoop *self) -{ - if (self->signal_source != NULL) { - g_source_destroy(self->signal_source); - self->signal_source = NULL; - } - - if (self->loop != NULL) { - g_main_loop_unref(self->loop); - self->loop = NULL; - } - - PyObject_Del(self); -} - -static int -pyg_main_loop_compare(PyGMainLoop *self, PyGMainLoop *v) -{ - if (self->loop == v->loop) return 0; - if (self->loop > v->loop) return -1; - return 1; -} - -static PyObject * -_wrap_g_main_loop_get_context (PyGMainLoop *loop) -{ - return pyg_main_context_new(g_main_loop_get_context(loop->loop)); -} - -static PyObject * -_wrap_g_main_loop_is_running (PyGMainLoop *self) -{ - return PyBool_FromLong(g_main_loop_is_running(self->loop)); -} - -static PyObject * -_wrap_g_main_loop_quit (PyGMainLoop *self) -{ - g_main_loop_quit(self->loop); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -_wrap_g_main_loop_run (PyGMainLoop *self) -{ - GMainLoop *prev_loop; - - prev_loop = pyg_save_current_main_loop(self->loop); - - pyg_begin_allow_threads; - g_main_loop_run(self->loop); - pyg_end_allow_threads; - - pyg_restore_current_main_loop(prev_loop); - - if (PyErr_Occurred()) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef _PyGMainLoop_methods[] = { - { "get_context", (PyCFunction)_wrap_g_main_loop_get_context, METH_NOARGS }, - { "is_running", (PyCFunction)_wrap_g_main_loop_is_running, METH_NOARGS }, - { "quit", (PyCFunction)_wrap_g_main_loop_quit, METH_NOARGS }, - { "run", (PyCFunction)_wrap_g_main_loop_run, METH_NOARGS }, - { NULL, NULL, 0 } -}; - -PyTypeObject PyGMainLoop_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "gobject.MainLoop", - sizeof(PyGMainLoop), - 0, - /* methods */ - (destructor)pyg_main_loop_dealloc, - (printfunc)0, - (getattrfunc)0, - (setattrfunc)0, - (cmpfunc)pyg_main_loop_compare, - (reprfunc)0, - 0, - 0, - 0, - (hashfunc)0, - (ternaryfunc)0, - (reprfunc)0, - (getattrofunc)0, - (setattrofunc)0, - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - NULL, - (traverseproc)0, - (inquiry)0, - (richcmpfunc)0, - 0, - (getiterfunc)0, - (iternextfunc)0, - _PyGMainLoop_methods, - 0, - 0, - NULL, - NULL, - (descrgetfunc)0, - (descrsetfunc)0, - 0, - (initproc)pyg_main_loop_new, -}; diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h index 4b41338b..5b71ed56 100644 --- a/gobject/pygobject-private.h +++ b/gobject/pygobject-private.h @@ -218,7 +218,8 @@ typedef struct { GSource *signal_source; } PyGMainLoop; -extern PyTypeObject PyGMainLoop_Type; +PyTypeObject *_PyGMainLoop_Type; +#define PyGMainLoop_Type (*_PyGMainLoop_Type) /* pygmaincontext */ @@ -227,8 +228,8 @@ typedef struct { GMainContext *context; } PyGMainContext; -extern PyTypeObject PyGMainContext_Type; -PyObject * pyg_main_context_new (GMainContext *context); +PyTypeObject *_PyGMainContext_Type; +#define PyGMainContext_Type (*_PyGMainContext_Type) /* pygparamspec */ diff --git a/gobject/pygobject.c b/gobject/pygobject.c index 45635003..d41971da 100644 --- a/gobject/pygobject.c +++ b/gobject/pygobject.c @@ -19,6 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ + +#include <pyglib.h> #include "pygobject-private.h" static void pygobject_dealloc(PyGObject *self); @@ -35,7 +37,7 @@ static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObj void pygobject_data_free(PyGObjectData *data) { - PyGILState_STATE state = pyg_gil_state_ensure(); + PyGILState_STATE state = pyglib_gil_state_ensure(); GSList *closures, *tmp; Py_DECREF(data->type); tmp = closures = data->closures; @@ -58,7 +60,7 @@ pygobject_data_free(PyGObjectData *data) g_warning("invalidated all closures, but data->closures != NULL !"); g_free(data); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } static inline PyGObjectData * @@ -629,14 +631,14 @@ pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref) PyGObject *self = (PyGObject*) data; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (is_last_ref) Py_DECREF(self); else Py_INCREF(self); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } /* Called when the inst_dict is first created; switches the @@ -744,7 +746,7 @@ pygobject_new_with_interfaces(GType gtype) PyObject *modules, *module; gchar *type_name, *mod_name, *gtype_name; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); bases = pyg_type_get_bases(gtype); py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0); @@ -787,7 +789,7 @@ pygobject_new_with_interfaces(GType gtype) if (type == NULL) { PyErr_Print(); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return NULL; } @@ -810,7 +812,7 @@ pygobject_new_with_interfaces(GType gtype) if (PyType_Ready(type) < 0) { g_warning ("couldn't make the type `%s' ready", type->tp_name); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return NULL; } /* insert type name in module dict */ @@ -824,7 +826,7 @@ pygobject_new_with_interfaces(GType gtype) Py_INCREF(type); g_type_set_qdata(gtype, pygobject_class_key, type); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return type; } @@ -2131,7 +2133,7 @@ pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy) self->obj = NULL; if (self->callback) { PyObject *retval; - PyGILState_STATE state = pyg_gil_state_ensure(); + PyGILState_STATE state = pyglib_gil_state_ensure(); retval = PyObject_Call(self->callback, self->user_data, NULL); if (retval) { if (retval != Py_None) @@ -2149,7 +2151,7 @@ pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy) self->have_floating_ref = FALSE; Py_DECREF((PyObject *) self); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } } diff --git a/gobject/pygobject.h b/gobject/pygobject.h index 76ab437f..592853af 100644 --- a/gobject/pygobject.h +++ b/gobject/pygobject.h @@ -176,7 +176,6 @@ struct _PyGObject_Functions { gboolean threads_enabled; int (*enable_threads) (void); - /* These 2 are deprecated */ int (*gil_state_ensure) (void); void (*gil_state_release) (int flag); @@ -254,6 +253,8 @@ struct _PyGObject_Functions *_PyGObject_API; #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 pygobject_construct (_PyGObject_API->pygobject_construct) @@ -265,7 +266,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)(); \ @@ -277,14 +277,6 @@ struct _PyGObject_Functions *_PyGObject_API; #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; \ diff --git a/gobject/pygoptiongroup.c b/gobject/pygoptiongroup.c index 64654017..770a4979 100644 --- a/gobject/pygoptiongroup.c +++ b/gobject/pygoptiongroup.c @@ -24,6 +24,7 @@ # include <config.h> #endif +#include <pyglib.h> #include "pygobject-private.h" #include "pygobject.h" @@ -43,7 +44,7 @@ static void destroy_g_group(PyGOptionGroup *self) { PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); self->group = NULL; Py_CLEAR(self->callback); @@ -56,7 +57,7 @@ destroy_g_group(PyGOptionGroup *self) Py_DECREF(self); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } static int @@ -107,7 +108,7 @@ arg_func(const gchar *option_name, PyGILState_STATE state; gboolean no_error; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (value == NULL) { @@ -123,13 +124,13 @@ arg_func(const gchar *option_name, if (ret != NULL) { Py_DECREF(ret); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return TRUE; } else { no_error = pyg_gerror_exception_check(error) != -1; - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return no_error; } } diff --git a/gobject/pygpointer.c b/gobject/pygpointer.c index 33caea22..6a7d9e2e 100644 --- a/gobject/pygpointer.c +++ b/gobject/pygpointer.c @@ -24,6 +24,7 @@ # include <config.h> #endif +#include <pyglib.h> #include "pygobject-private.h" static void @@ -185,11 +186,11 @@ pyg_pointer_new(GType pointer_type, gpointer pointer) PyTypeObject *tp; g_return_val_if_fail(pointer_type != 0, NULL); - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (!pointer) { Py_INCREF(Py_None); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return Py_None; } @@ -198,7 +199,7 @@ pyg_pointer_new(GType pointer_type, gpointer pointer) tp = (PyTypeObject *)&PyGPointer_Type; /* fallback */ self = PyObject_NEW(PyGPointer, tp); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); if (self == NULL) return NULL; diff --git a/gobject/pygsource.c b/gobject/pygsource.c index 53d0cae7..ae667dc9 100644 --- a/gobject/pygsource.c +++ b/gobject/pygsource.c @@ -30,6 +30,7 @@ #include "pygobject-private.h" #include "pythread.h" #include <structmember.h> +#include <pyglib.h> #define CHECK_DESTROYED(self, ret) G_STMT_START { \ @@ -174,7 +175,7 @@ pyg_source_get_context(PyGSource *self) context = g_source_get_context(self->source); if (context) { - return pyg_main_context_new(context); + return pyglib_main_context_new(context); } else { Py_INCREF(Py_None); return Py_None; @@ -397,7 +398,7 @@ pyg_source_prepare(GSource *source, gint *timeout) gboolean got_err = TRUE; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); t = PyObject_CallMethod(pysource->obj, "prepare", NULL); @@ -433,7 +434,7 @@ bail: Py_XDECREF(t); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return ret; } @@ -446,7 +447,7 @@ pyg_source_check(GSource *source) gboolean ret; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); t = PyObject_CallMethod(pysource->obj, "check", NULL); @@ -458,7 +459,7 @@ pyg_source_check(GSource *source) Py_DECREF(t); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return ret; } @@ -471,7 +472,7 @@ pyg_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) gboolean ret; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); if (callback) { tuple = user_data; @@ -493,7 +494,7 @@ pyg_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) Py_DECREF(t); } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return ret; } @@ -505,7 +506,7 @@ pyg_source_finalize(GSource *source) PyObject *func, *t; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); func = PyObject_GetAttrString(pysource->obj, "finalize"); if (func) { @@ -519,7 +520,7 @@ pyg_source_finalize(GSource *source) } } - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } static GSourceFuncs pyg_source_funcs = diff --git a/gobject/pygtype.c b/gobject/pygtype.c index 897234a7..eb5b0bca 100644 --- a/gobject/pygtype.c +++ b/gobject/pygtype.c @@ -20,6 +20,8 @@ * USA */ +#include <pyglib.h> + #include "pygobject-private.h" /* -------------- __gtype__ objects ---------------------------- */ @@ -1076,11 +1078,11 @@ pyg_closure_invalidate(gpointer data, GClosure *closure) PyGClosure *pc = (PyGClosure *)closure; PyGILState_STATE state; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); Py_XDECREF(pc->callback); Py_XDECREF(pc->extra_args); Py_XDECREF(pc->swap_data); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); pc->callback = NULL; pc->extra_args = NULL; @@ -1100,7 +1102,7 @@ pyg_closure_marshal(GClosure *closure, PyObject *params, *ret; guint i; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); @@ -1148,7 +1150,7 @@ pyg_closure_marshal(GClosure *closure, out: Py_DECREF(params); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } /** @@ -1241,7 +1243,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, PyObject *params, *ret; guint i, len; - state = pyg_gil_state_ensure(); + state = pyglib_gil_state_ensure(); g_return_if_fail(invocation_hint != NULL); /* get the object passed as the first argument to the closure */ @@ -1267,7 +1269,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, if (!method) { PyErr_Clear(); Py_DECREF(object_wrapper); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return; } Py_DECREF(object_wrapper); @@ -1281,7 +1283,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, /* error condition */ if (!item) { Py_DECREF(params); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return; } PyTuple_SetItem(params, i - 1, item); @@ -1308,7 +1310,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, PyErr_Print(); Py_DECREF(method); Py_DECREF(params); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); return; } Py_DECREF(method); @@ -1316,7 +1318,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, if (return_value) pyg_value_from_pyobject(return_value, ret); Py_DECREF(ret); - pyg_gil_state_release(state); + pyglib_gil_state_release(state); } /** |