? t.tmp Index: Makefile.am =================================================================== RCS file: /cvs/gnome/gnome-python/pygtk/gobject/Makefile.am,v retrieving revision 1.3 diff -u -p -r1.3 Makefile.am --- Makefile.am 29 Jul 2004 18:05:14 -0000 1.3 +++ Makefile.am 2 Feb 2005 11:20:06 -0000 @@ -13,6 +13,7 @@ if PLATFORM_WIN32 common_ldflags += -no-undefined endif +gobject_la_CFLAGS = $(GLIB_CFLAGS) gobject_la_LDFLAGS = $(common_ldflags) -export-symbols-regex initgobject gobject_la_LIBADD = $(GLIB_LIBS) gobject_la_SOURCES = \ @@ -28,3 +29,7 @@ gobject_la_SOURCES = \ pygparamspec.c \ pygpointer.c \ pygtype.c + +if PLATFORM_WIN32 +gobject_la_CFLAGS += -DPLATFORM_WIN32 +endif Index: pygmainloop.c =================================================================== RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygmainloop.c,v retrieving revision 1.4 diff -u -p -r1.4 pygmainloop.c --- pygmainloop.c 4 Aug 2004 14:52:52 -0000 1.4 +++ pygmainloop.c 2 Feb 2005 11:20:06 -0000 @@ -27,6 +27,89 @@ #include "pygobject-private.h" +typedef struct +{ + GSource source; + GMainLoop *main_loop; +} PyGSignalWatchSource; + +static gboolean +pyg_signal_watch_prepare(GSource *source, + int *timeout) +{ + /* 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. So, we need to time out and check for signals + * regularily too. + * Also, on Windows g_poll() won't be interrupted by a signal + * (AFAIK), so we need the timeout there too. + */ +#ifndef PLATFORM_WIN32 + if (pyg_threads_enabled) +#endif + *timeout = 100; + + return FALSE; +} + +static gboolean +pyg_signal_watch_check(GSource *source) +{ + PyGSignalWatchSource *signal_watch_source = (PyGSignalWatchSource *)source; + PyGILState_STATE state; + + state = pyg_gil_state_ensure(); + + if (PyErr_CheckSignals() == -1 || PyErr_Occurred()) + g_main_loop_quit(signal_watch_source->main_loop); + + pyg_gil_state_release(state); + + return FALSE; +} + +static gboolean +pyg_signal_watch_dispatch(GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + /* We should neve be dispatched */ + g_assert_not_reached(); + return TRUE; +} + +static void +pyg_signal_watch_finalize(GSource *source) +{ + PyGSignalWatchSource *signal_watch_source = (PyGSignalWatchSource *)source; + + g_main_loop_unref(signal_watch_source->main_loop); + signal_watch_source->main_loop = NULL; +} + +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(GMainLoop *main_loop) +{ + GSource *source; + PyGSignalWatchSource *signal_watch_source; + + source = g_source_new(&pyg_signal_watch_funcs, sizeof(PyGSignalWatchSource)); + signal_watch_source = (PyGSignalWatchSource *)source; + + signal_watch_source->main_loop = g_main_loop_ref(main_loop); + + return source; +} + static int pyg_main_loop_new(PyGMainLoop *self, PyObject *args, PyObject *kwargs) { @@ -55,9 +138,29 @@ pyg_main_loop_new(PyGMainLoop *self, PyO } self->loop = g_main_loop_new(context, is_running); + + self->signal_source = pyg_signal_watch_new(self->loop); + 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) { @@ -123,7 +226,7 @@ PyTypeObject PyGMainLoop_Type = { sizeof(PyGMainLoop), 0, /* methods */ - (destructor)0, + (destructor)pyg_main_loop_dealloc, (printfunc)0, (getattrfunc)0, (setattrfunc)0, Index: pygobject-private.h =================================================================== RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject-private.h,v retrieving revision 1.27 diff -u -p -r1.27 pygobject-private.h --- pygobject-private.h 10 Jan 2005 23:39:04 -0000 1.27 +++ pygobject-private.h 2 Feb 2005 11:20:06 -0000 @@ -145,6 +145,7 @@ extern PyObject * pyg_enum_from_gtype (G typedef struct { PyObject_HEAD GMainLoop *loop; + GSource *signal_source; } PyGMainLoop; extern PyTypeObject PyGMainLoop_Type;