Index: configure.ac
===================================================================
--- configure.ac	(revision 722)
+++ configure.ac	(working copy)
@@ -69,6 +69,22 @@
 
 AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
 
+AC_MSG_CHECKING([for PySignal_SetWakeupFd in Python.h])
+py_prefix=`$PYTHON -c "import sys; print sys.prefix"`
+PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
+old_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$PYTHON_INCLUDES"
+AC_TRY_COMPILE([#include <Python.h>],
+  [PySignal_SetWakeupFd(0);],
+  setwakeupfd_ok=yes,
+  setwakeupfd_ok=no)
+AC_MSG_RESULT($setwakeupfd_ok)
+if test "x$setwakeupfd_ok" != xno; then
+  AC_DEFINE(HAVE_PYSIGNAL_SETWAKEUPFD, 1,
+                [Define to 1 if PySignal_SetWakeupFd is available])
+fi
+CPPFLAGS=$old_CPPFLAGS
+
 PLATFORM=`$PYTHON -c "from distutils import util; print util.get_platform()"`
 AC_SUBST(PLATFORM)
 
Index: gobject/pygmainloop.c
===================================================================
--- gobject/pygmainloop.c	(revision 722)
+++ gobject/pygmainloop.c	(working copy)
@@ -102,10 +102,41 @@ pyg_get_current_main_loop (void)
 }
 #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;
+
+#ifndef PLATFORM_WIN32
+    if (!pyg_threads_enabled)
+	return;
+#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
+     */
+    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
     /* 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
@@ -114,10 +145,8 @@ pyg_signal_watch_prepare(GSource *source
      * 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)
+    *timeout = 1000;
 #endif
-	*timeout = 1000;
 
     return FALSE;
 }
@@ -143,27 +172,41 @@ pyg_signal_watch_check(GSource *source)
 }
 
 static gboolean
-pyg_signal_watch_dispatch(GSource    *source,
-			  GSourceFunc callback,
-			  gpointer    user_data)
+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,
-    NULL
+    pyg_signal_watch_finalize
 };
 
 static GSource *
 pyg_signal_watch_new(void)
 {
-    return g_source_new(&pyg_signal_watch_funcs, sizeof(GSource));
+    return g_source_new(&pyg_signal_watch_funcs, sizeof(PySignalWatchSource));
 }
 
 static int
