Index: gobject/pygsource.c
===================================================================
--- gobject/pygsource.c	(revision 746)
+++ gobject/pygsource.c	(working copy)
@@ -2,8 +2,10 @@
  * pygtk- Python bindings for the GTK toolkit.
  * Copyright (C) 1998-2003  James Henstridge
  * Copyright (C) 2005       Oracle
+ * Copyright (C) 2008       Bryan Silverthorn
  *
  * Author: Manish Singh <manish.singh@oracle.com>
+ * Author: Bryan Silverthorn <bcs26@cornell.edu>
  *
  *   pygsource.c: GSource wrapper
  *
@@ -23,6 +25,29 @@
  * USA
  */
 
+/* A few notes on GSource memory management:
+ *
+ * 1. On construction: incref wrapper unconditionally (because it may
+ *    become attached in the future, not necessarily via the wrapper).
+ * 2. On destroy: decref wrapper unconditionally.
+ * 3. On visit:
+ *    1. If source refcount is one and no finalize method is present,
+ *       visit self.
+ *    2. If finalize method is present, do nothing; it's uncollectable.
+ * 4. On clear: clear as expected, decref source.
+ * 5. On dealloc:
+ *    1. Clear weak refs. (Must be done _first_.)
+ *    2. Py_INCREF the wrapper to avoid double-decref in finalization.
+ *       (Incrementing the wrapper's refcount also breaks weak refs.)
+ *    3. Clear and free the wrapper as expected.
+ * 6. On finalize: if wrapper still exists, call finalize, if present.
+ *
+ * Be aware that these rules _still_ do not handle every case correctly.
+ * For example, a source callback might reference the context to which
+ * the source is attached; this cycle will permanently prevent either
+ * source or context from being collected.
+ */
+
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
@@ -31,15 +56,6 @@
 #include "pythread.h"
 #include <structmember.h>
 
-
-#define CHECK_DESTROYED(self, ret)			G_STMT_START {	\
-    if ((self)->source == NULL) {					\
-	PyErr_SetString(PyExc_RuntimeError, "source is destroyed");	\
-	return (ret);							\
-    }									\
-} G_STMT_END
-
-
 typedef struct {
     PyObject_HEAD
     GSource *source;
@@ -54,26 +70,55 @@
     PyObject *obj;
 } PyGRealSource;
 
+static gboolean
+set_error_if_destroyed(PyGSource *self)
+{
+    if (!self->source)
+    {
+        PyErr_SetString(PyExc_ValueError, "operation on deallocated source");
+
+        return TRUE;
+    }
+    else if (g_source_is_destroyed(self->source))
+    {
+        PyErr_SetString(PyExc_ValueError, "operation on destroyed source");
+
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
 static PyObject *
 source_repr(PyGSource *self, const char *type)
 {
-    gchar buf[256], *desc;
- 
-    if (self->source) {
-	if (g_source_get_context(self->source))
-	    desc = "attached";
-	else
-	    desc = "unattached";
+    gchar buf[256];
+    gchar *desc;
+
+    if (g_source_is_destroyed(self->source)) {
+        desc = "destroyed";
     } else {
-	desc = "destroyed";
+        if (g_source_get_context(self->source))
+            desc = "attached";
+        else
+            desc = "unattached";
     }
 
     if (type)
-	g_snprintf(buf, sizeof(buf), "<%s glib %s source at 0x%lx>",
-		   desc, type, (long) self);
+        g_snprintf(
+            buf,
+            sizeof(buf),
+            "<%s glib %s source at 0x%lx>",
+            desc,
+            type,
+            (long)self);
     else
-	g_snprintf(buf, sizeof(buf), "<%s glib source at 0x%lx>",
-		   desc, (long) self);
+        g_snprintf(
+            buf,
+            sizeof(buf),
+            "<%s glib source at 0x%lx>",
+            desc,
+            (long)self);
 
     return PyString_FromString(buf);
 }
@@ -87,97 +132,106 @@
     guint id;
 
     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
-				      "|O!:attach", kwlist,
-				      &PyGMainContext_Type, &py_context))
-	return NULL;
+                "|O!:attach", kwlist,
+                &PyGMainContext_Type, &py_context))
+        return NULL;
 
     if (py_context)
-	context = py_context->context;
+        context = py_context->context;
 
-    CHECK_DESTROYED(self, NULL);
+    if (set_error_if_destroyed(self))
+        return NULL;
 
-    if (self->python_source) {
-	PyGRealSource *pysource = (PyGRealSource *)self->source;
-	Py_INCREF(pysource->obj);
-    }
+    id = g_source_attach(self->source, context);
 
-    id = g_source_attach(self->source, context);
     return PyInt_FromLong(id);
 }
 
 static PyObject *
 pyg_source_destroy(PyGSource *self)
 {
-    CHECK_DESTROYED(self, NULL);
+    if (set_error_if_destroyed(self))
+        return NULL;
 
-    if (self->python_source && self->source->context) {
-	PyGRealSource *pysource = (PyGRealSource *)self->source;
-	Py_DECREF(pysource->obj);
-    }
-
     g_source_destroy(self->source);
-    self->source = NULL;
 
+    Py_DECREF(self);
+
     Py_INCREF(Py_None);
+
     return Py_None;
 }
 
 static PyObject *
 pyg_source_set_callback(PyGSource *self, PyObject *args)
 {
-    PyObject *first, *callback, *cbargs = NULL, *data;
+    PyObject *first, *callback, *cbargs, *data;
     gint len;
 
-    CHECK_DESTROYED(self, NULL);
+    if (set_error_if_destroyed(self))
+        return NULL;
 
     len = PyTuple_Size (args);
+
     if (len < 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"set_callback requires at least 1 argument");
-	return NULL;
+        PyErr_SetString(PyExc_TypeError,
+                "set_callback requires at least 1 argument");
+
+        return NULL;
     }
 
     first = PySequence_GetSlice(args, 0, 1);
+
     if (!PyArg_ParseTuple(first, "O:set_callback", &callback)) {
-	Py_DECREF (first);
-	return NULL;
+        Py_DECREF(first);
+
+        return NULL;
     }
+
     Py_DECREF(first);
 
     if (!PyCallable_Check(callback)) {
-	PyErr_SetString(PyExc_TypeError, "first argument not callable");
-	return NULL;
+        PyErr_SetString(PyExc_TypeError, "first argument not callable");
+
+        return NULL;
     }
 
     cbargs = PySequence_GetSlice(args, 1, len);
-    if (cbargs == NULL)
-	return NULL;
 
+    if (!cbargs)
+        return NULL;
+
     data = Py_BuildValue("(ON)", callback, cbargs);
-    if (data == NULL)
-	return NULL;
 
-    g_source_set_callback(self->source, pyg_handler_marshal, data,
-			  pyg_destroy_notify);
+    if (!data)
+        return NULL;
 
+    g_source_set_callback(
+        self->source,
+        pyg_handler_marshal,
+        data,
+        pyg_destroy_notify);
+
     Py_INCREF(Py_None);
+
     return Py_None;
 }
 
 static PyObject *
 pyg_source_get_context(PyGSource *self)
 {
-    GMainContext *context;
+    if (set_error_if_destroyed(self)) {
+        return NULL;
+    } else {
+        GMainContext *context = g_source_get_context(self->source);
 
-    CHECK_DESTROYED(self, NULL);
+        if (context) {
+            return pyg_main_context_new(context);
+        } else {
+            Py_INCREF(Py_None);
 
-    context = g_source_get_context(self->source);
-
-    if (context) {
-	return pyg_main_context_new(context);
-    } else {
-	Py_INCREF(Py_None);
-	return Py_None;
+            return Py_None;
+        }
     }
 }
 
@@ -188,23 +242,25 @@
     PyGPollFD *fd;
 
     if (!self->python_source) {
-	PyErr_SetString(PyExc_TypeError,
-			"add_poll can only be used with sources "
-			"implemented in python");
-	return NULL;
-    }
+        PyErr_SetString(PyExc_TypeError,
+                "add_poll can only be used with sources "
+                "implemented in python");
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "O!:add_poll", kwlist,
-				     &PyGPollFD_Type, &fd))
-	return NULL;
+        return NULL;
+    } else if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                "O!:add_poll", kwlist,
+                &PyGPollFD_Type, &fd)) {
+        return NULL;
+    } else {
+        if(set_error_if_destroyed(self))
+            return NULL;
 
-    CHECK_DESTROYED(self, NULL);
+        g_source_add_poll(self->source, &fd->pollfd);
 
-    g_source_add_poll(self->source, &fd->pollfd);
+        Py_INCREF(Py_None);
 
-    Py_INCREF(Py_None);
-    return Py_None;
+        return Py_None;
+    }
 }
 
 static PyObject *
@@ -214,36 +270,43 @@
     PyGPollFD *fd;
 
     if (!self->python_source) {
-	PyErr_SetString(PyExc_TypeError,
-			"remove_poll can only be used with sources "
-			"implemented in python");
-	return NULL;
-    }
+        PyErr_SetString(PyExc_TypeError,
+                "remove_poll can only be used with sources "
+                "implemented in python");
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "O!:remove_poll", kwlist,
-				     &PyGPollFD_Type, &fd))
-	return NULL;
+        return NULL;
+    } else if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                "O!:remove_poll", kwlist,
+                &PyGPollFD_Type, &fd)) {
 
-    CHECK_DESTROYED(self, NULL);
+        return NULL;
+    } else if (set_error_if_destroyed(self)) {
+        return NULL;
+    } else {
+        g_source_remove_poll(self->source, &fd->pollfd);
 
-    g_source_remove_poll(self->source, &fd->pollfd);
+        Py_INCREF(Py_None);
 
-    Py_INCREF(Py_None);
-    return Py_None;
+        return Py_None;
+    }
 }
 
 static PyObject *
 pyg_source_get_current_time(PyGSource *self)
 {
-    GTimeVal timeval;
-    double   ret;
+    if (set_error_if_destroyed(self)) {
+        return NULL;
+    }
+    else {
+        GTimeVal timeval;
+        double ret;
 
-    CHECK_DESTROYED(self, NULL);
+        g_source_get_current_time(self->source, &timeval);
 
-    g_source_get_current_time(self->source, &timeval);
-    ret = (double)timeval.tv_sec + (double)timeval.tv_usec * 0.000001;
-    return PyFloat_FromDouble(ret);
+        ret = (double)timeval.tv_sec + (double)timeval.tv_usec * 0.000001;
+
+        return PyFloat_FromDouble(ret);
+    }
 }
 
 static PyMethodDef pyg_source_methods[] = {
@@ -260,86 +323,91 @@
 static PyObject *
 pyg_source_get_dict(PyGSource *self, void *closure)
 {
-    if (self->inst_dict == NULL) {
-	self->inst_dict = PyDict_New();
-	if (self->inst_dict == NULL)
-	    return NULL;
+    if (!self->inst_dict) {
+        self->inst_dict = PyDict_New();
+
+        if (!self->inst_dict)
+            return NULL;
     }
 
     Py_INCREF(self->inst_dict);
+
     return self->inst_dict;
 }
 
 static PyObject *
 pyg_source_get_priority(PyGSource *self, void *closure)
 {
-    CHECK_DESTROYED(self, NULL);
-
-    return PyInt_FromLong(g_source_get_priority(self->source));
+    if (set_error_if_destroyed(self))
+        return NULL;
+    else
+        return PyInt_FromLong(g_source_get_priority(self->source));
 }
 
 static int
 pyg_source_set_priority(PyGSource *self, PyObject *value, void *closure)
 {
-    CHECK_DESTROYED(self, -1);
+    if(set_error_if_destroyed(self)) {
+        return -1;
+    } else if (!value) {
+        PyErr_SetString(PyExc_TypeError, "cannot delete priority");
 
-    if (value == NULL) {
-	PyErr_SetString(PyExc_TypeError, "cannot delete priority");
-	return -1;
-    }
+        return -1;
+    } else if (!PyInt_Check(value)) {
+        PyErr_SetString(PyExc_TypeError, "type mismatch");
 
-    if (!PyInt_Check(value)) {
-	PyErr_SetString(PyExc_TypeError, "type mismatch");
-	return -1;
+        return -1;
+    } else {
+        g_source_set_priority(self->source, PyInt_AsLong(value));
+
+        return 0;
     }
-
-    g_source_set_priority(self->source, PyInt_AsLong(value));
-
-    return 0;
 }
 
 static PyObject *
 pyg_source_get_can_recurse(PyGSource *self, void *closure)
 {
-    CHECK_DESTROYED(self, NULL);
-
-    return PyBool_FromLong(g_source_get_can_recurse(self->source));
+    if(set_error_if_destroyed(self))
+        return NULL;
+    else
+        return PyBool_FromLong(g_source_get_can_recurse(self->source));
 }
 
 static int
 pyg_source_set_can_recurse(PyGSource *self, PyObject *value, void *closure)
 {
-    CHECK_DESTROYED(self, -1);
+    if(set_error_if_destroyed(self)) {
+        return -1;
+    } else if (!value) {
+        PyErr_SetString(PyExc_TypeError, "cannot delete can_recurse");
 
-    if (value == NULL) {
-	PyErr_SetString(PyExc_TypeError, "cannot delete can_recurse");
-	return -1;
+        return -1;
+    } else {
+        g_source_set_can_recurse(self->source, PyObject_IsTrue(value));
+
+        return 0;
     }
-
-    g_source_set_can_recurse(self->source, PyObject_IsTrue(value));
-
-    return 0;
 }
 
 static PyObject *
 pyg_source_get_id(PyGSource *self, void *closure)
 {
-    CHECK_DESTROYED(self, NULL);
+    if(set_error_if_destroyed(self)) {
+        return NULL;
+    } else if (!g_source_get_context(self->source)) {
+        PyErr_SetString(PyExc_RuntimeError, "source is not attached");
 
-    if (g_source_get_context(self->source) == NULL) {
-	PyErr_SetString(PyExc_RuntimeError, "source is not attached");
-	return NULL;
-    }
-
-    return PyInt_FromLong(g_source_get_id(self->source));
+        return NULL;
+    } else
+        return PyInt_FromLong(g_source_get_id(self->source));
 }
 
 static PyGetSetDef pyg_source_getsets[] = {
-    { "__dict__", (getter)pyg_source_get_dict,  (setter)0 },
+    { "__dict__", (getter)pyg_source_get_dict, (setter)NULL },
     {"priority", (getter)pyg_source_get_priority, (setter)pyg_source_set_priority },
     {"can_recurse", (getter)pyg_source_get_can_recurse, (setter)pyg_source_set_can_recurse },
-    {"id", (getter)pyg_source_get_id, (setter)0 },
-    {NULL, 0, 0}
+    {"id", (getter)pyg_source_get_id, (setter)NULL },
+    {NULL, NULL, NULL }
 };
 
 static PyObject *
@@ -348,13 +416,19 @@
     return source_repr(self, NULL);
 }
 
+/* We can (and should) self-collect if:
+ *  - wrapper is referenced only by source, and
+ *  - we don't have a finalize method.
+ */
 static int
 pyg_source_traverse(PyGSource *self, visitproc visit, void *arg)
 {
-    int ret = 0;
+    Py_VISIT(self->inst_dict);
 
-    if (self->inst_dict) ret = visit(self->inst_dict, arg);
-    if (ret != 0) return ret;
+    if (self->source
+            && self->source->ref_count == 1
+            && !PyObject_HasAttrString((PyObject *)self, "finalize"))
+        Py_VISIT(self);
 
     return 0;
 }
@@ -362,76 +436,66 @@
 static int
 pyg_source_clear(PyGSource *self)
 {
-    PyObject *tmp;
+    Py_CLEAR(self->inst_dict);
 
-    tmp = self->inst_dict;
-    self->inst_dict = NULL;
-    Py_XDECREF(tmp);
+    if(self->source) {
+        /* make sure we can't touch the source again, then unref
+         */
+        GSource* source = self->source;
 
-    if (self->source) {
-	g_source_unref(self->source);
-	self->source = NULL;
+        self->source = NULL;
+
+        g_source_unref(source);
     }
 
     return 0;
 }
 
-static void
-pyg_source_dealloc(PyGSource *self)
-{
-    PyObject_ClearWeakRefs((PyObject *)self);
-
-    PyObject_GC_UnTrack((PyObject *)self);
-
-    pyg_source_clear(self);
-
-    PyObject_GC_Del(self);
-}
-
 static gboolean
 pyg_source_prepare(GSource *source, gint *timeout)
 {
     PyGRealSource *pysource = (PyGRealSource *)source;
+    PyGILState_STATE state;
+    gboolean got_err = TRUE;
+    gboolean ret = FALSE;
     PyObject *t;
-    gboolean ret = FALSE;
-    gboolean got_err = TRUE;
-    PyGILState_STATE state;
 
     state = pyg_gil_state_ensure();
 
     t = PyObject_CallMethod(pysource->obj, "prepare", NULL);
 
     if (t == NULL) {
-	goto bail;
+        goto bail;
     } else if (!PyObject_IsTrue(t)) {
-	got_err = FALSE;
-	goto bail;
+        got_err = FALSE;
+        goto bail;
     } else if (!PyTuple_Check(t)) {
-	PyErr_SetString(PyExc_TypeError,
-			"source prepare function must return a tuple or False");
-	goto bail;
+        PyErr_SetString(PyExc_TypeError,
+                "source prepare function must return a tuple or False");
+        goto bail;
     } else if (PyTuple_Size(t) != 2) {
-	PyErr_SetString(PyExc_TypeError,
-			"source prepare function return tuple must be exactly "
-			"2 elements long");
-	goto bail;
+        PyErr_SetString(PyExc_TypeError,
+                "source prepare function return tuple must be exactly "
+                "2 elements long");
+        goto bail;
     }
 
     ret = PyObject_IsTrue(PyTuple_GET_ITEM(t, 0));
 
     if (ret) {
-	*timeout = PyInt_AsLong(PyTuple_GET_ITEM(t, 1));
-	if (*timeout == -1 && PyErr_Occurred()) {
-	    ret = FALSE;
-	    goto bail;
-	}
+        *timeout = PyInt_AsLong(PyTuple_GET_ITEM(t, 1));
+
+        if (*timeout == -1 && PyErr_Occurred()) {
+            ret = FALSE;
+            goto bail;
+        }
     }
 
     got_err = FALSE;
 
 bail:
     if (got_err)
-	PyErr_Print();
+        PyErr_Print();
 
     Py_XDECREF(t);
 
@@ -444,20 +508,20 @@
 pyg_source_check(GSource *source)
 {
     PyGRealSource *pysource = (PyGRealSource *)source;
+    PyGILState_STATE state;
+    gboolean ret;
     PyObject *t;
-    gboolean ret;
-    PyGILState_STATE state;
 
     state = pyg_gil_state_ensure();
 
     t = PyObject_CallMethod(pysource->obj, "check", NULL);
 
-    if (t == NULL) {
-	PyErr_Print();
-	ret = FALSE;
+    if (t) {
+        ret = PyObject_IsTrue(t);
+        Py_DECREF(t);
     } else {
-	ret = PyObject_IsTrue(t);
-	Py_DECREF(t);
+        PyErr_Print();
+        ret = FALSE;
     }
 
     pyg_gil_state_release(state);
@@ -469,30 +533,30 @@
 pyg_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
 {
     PyGRealSource *pysource = (PyGRealSource *)source;
-    PyObject *func, *args, *tuple, *t;
+    PyObject *func, *args, *t;
+    PyGILState_STATE state;
     gboolean ret;
-    PyGILState_STATE state;
 
     state = pyg_gil_state_ensure();
 
     if (callback) {
-	tuple = user_data;
+        PyObject *tuple = user_data;
 
-	func = PyTuple_GetItem(tuple, 0);
+        func = PyTuple_GetItem(tuple, 0);
         args = PyTuple_GetItem(tuple, 1);
     } else {
-	func = Py_None;
-	args = Py_None;
+        func = Py_None;
+        args = Py_None;
     }
 
     t = PyObject_CallMethod(pysource->obj, "dispatch", "OO", func, args);
 
-    if (t == NULL) {
-	PyErr_Print();
-	ret = FALSE;
+    if (t) {
+        ret = PyObject_IsTrue(t);
+        Py_DECREF(t);
     } else {
-	ret = PyObject_IsTrue(t);
-	Py_DECREF(t);
+        PyErr_Print();
+        ret = FALSE;
     }
 
     pyg_gil_state_release(state);
@@ -504,21 +568,23 @@
 pyg_source_finalize(GSource *source)
 {
     PyGRealSource *pysource = (PyGRealSource *)source;
-    PyObject *func, *t;
     PyGILState_STATE state;
+    PyObject *finalize;
 
     state = pyg_gil_state_ensure();
+    finalize = PyObject_GetAttrString(pysource->obj, "finalize");
 
-    func = PyObject_GetAttrString(pysource->obj, "finalize");
-    if (func) {
-	t = PyObject_CallObject(func, NULL);
-	Py_DECREF(func);
+    if (finalize) {
+        PyObject *t = PyObject_CallObject(finalize, NULL);
 
-	if (t == NULL) {
-	    PyErr_Print();
-	} else {
-	    Py_DECREF(t);
-	}
+        Py_DECREF(finalize);
+
+        if (t)
+            Py_DECREF(t);
+        else
+            PyErr_Print();
+    } else {
+        PyErr_Clear();
     }
 
     pyg_gil_state_release(state);
@@ -540,13 +606,14 @@
     self->source = g_source_new(&pyg_source_funcs, sizeof(PyGRealSource));
 
     pysource = (PyGRealSource *)self->source;
-    pysource->obj = (PyObject*)self;
+    pysource->obj = (PyObject *)self;
 
     self->inst_dict = NULL;
     self->weakreflist = NULL;
-
     self->python_source = TRUE;
 
+    Py_INCREF(self);
+
     return 0;
 }
 
@@ -556,6 +623,29 @@
     PyObject_GC_Del(op);
 }
 
+static void
+pyg_source_dealloc(PyGSource *self)
+{
+    if (self->weakreflist)
+        PyObject_ClearWeakRefs((PyObject *)self);
+
+    /* Keep the object alive through (potential) finalization ---
+     * we eventually free it with a positive refcount; also note
+     * that we assume finalization cannot occur through the GC.
+     */
+    Py_INCREF(self);
+
+    PyObject_GC_UnTrack(self);
+
+    pyg_source_clear(self);
+
+    if (self->ob_refcnt <= 1) {
+        /* The object was not resurrected by the finalizer.
+         */
+        pyg_source_free((PyObject *)self);
+    }
+}
+
 PyTypeObject PyGSource_Type = {
     PyObject_HEAD_INIT(NULL)
     0,					/* ob_size */
@@ -615,20 +705,21 @@
     gint priority = G_PRIORITY_DEFAULT_IDLE;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "|i:gobject.Idle.__init__", kwlist,
-				     &priority))
-	return -1;
+                "|i:gobject.Idle.__init__", kwlist,
+                &priority))
+        return -1;
 
-    self->source = g_idle_source_new ();
+    self->source = g_idle_source_new();
 
     if (priority != G_PRIORITY_DEFAULT_IDLE)
-	g_source_set_priority(self->source, priority);
+        g_source_set_priority(self->source, priority);
 
     self->inst_dict = NULL;
     self->weakreflist = NULL;
-
     self->python_source = FALSE;
 
+    Py_INCREF(self);
+
     return 0;
 }
 
@@ -653,8 +744,7 @@
     (getattrofunc)0,			/* tp_getattro */
     (setattrofunc)0,			/* tp_setattro */
     0,					/* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
-      Py_TPFLAGS_HAVE_GC,		/* tp_flags */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     NULL,				/* tp_doc */
     (traverseproc)0,			/* tp_traverse */
     (inquiry)0,				/* tp_clear */
@@ -692,20 +782,21 @@
     guint interval;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "I|i:gobject.Timeout.__init__", kwlist,
-				     &interval, &priority))
-	return -1;
+                "I|i:gobject.Timeout.__init__", kwlist,
+                &interval, &priority))
+        return -1;
 
     self->source = g_timeout_source_new(interval);
 
     if (priority != G_PRIORITY_DEFAULT)
-	g_source_set_priority(self->source, priority);
+        g_source_set_priority(self->source, priority);
 
     self->inst_dict = NULL;
     self->weakreflist = NULL;
-
     self->python_source = FALSE;
 
+    Py_INCREF(self);
+
     return 0;
 }
 
@@ -730,8 +821,7 @@
     (getattrofunc)0,			/* tp_getattro */
     (setattrofunc)0,			/* tp_setattro */
     0,					/* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
-      Py_TPFLAGS_HAVE_GC,		/* tp_flags */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     NULL,				/* tp_doc */
     (traverseproc)0,			/* tp_traverse */
     (inquiry)0,				/* tp_clear */
@@ -773,8 +863,8 @@
 pyg_poll_fd_repr(PyGPollFD *self)
 {
     return PyString_FromFormat("<GPollFD %d (%d) at 0x%lx>",
-			       self->pollfd.fd, self->pollfd.events,
-			       (long)self);
+            self->pollfd.fd, self->pollfd.events,
+            (long)self);
 }
 
 static int
@@ -786,20 +876,21 @@
     gushort events;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "OH:gobject.PollFD.__init__", kwlist,
-				     &o, &events))
-	return -1;
+                "OH:gobject.PollFD.__init__", kwlist,
+                &o, &events))
+        return -1;
 
     fd = PyObject_AsFileDescriptor(o);
+
     if (fd == -1)
-	return -1;
+        return -1;
 
     self->pollfd.fd = fd;
     self->pollfd.events = events;
     self->pollfd.revents = 0;
+    self->fd_obj = o;
 
     Py_INCREF(o);
-    self->fd_obj = o;
 
     return 0;
 }
@@ -848,3 +939,4 @@
     (inquiry)0,				/* tp_is_gc */
     (PyObject *)0,			/* tp_bases */
 };
+
