diff Modules/_threadmodule.c @ 86947:35fdb15b4939

Issue #19437: Fix _threading.RLock constructor (rlock_new), call Py_DECREF(self) if PyThread_allocate_lock() failed instead of calling directly type->tp_free(self), to keep the chained list of objects consistent when Python is compiled in debug mode fails, don't consume the row (restore it) and fail immediatly (don't call pysqlite_step())
author Victor Stinner <victor.stinner@gmail.com>
date Tue, 05 Nov 2013 15:10:19 +0100
parents d52b68edbca6
children 954167ce92a3
line wrap: on
line diff
--- a/Modules/_threadmodule.c	Tue Nov 05 14:50:30 2013 +0100
+++ b/Modules/_threadmodule.c	Tue Nov 05 15:10:19 2013 +0100
@@ -68,7 +68,7 @@
             Py_BEGIN_ALLOW_THREADS
             r = PyThread_acquire_lock_timed(lock, microseconds, 1);
             Py_END_ALLOW_THREADS
-        } 
+        }
 
         if (r == PY_LOCK_INTR) {
             /* Run signal handlers if we were interrupted.  Propagate
@@ -255,14 +255,17 @@
 static void
 rlock_dealloc(rlockobject *self)
 {
-    assert(self->rlock_lock);
     if (self->in_weakreflist != NULL)
         PyObject_ClearWeakRefs((PyObject *) self);
-    /* Unlock the lock so it's safe to free it */
-    if (self->rlock_count > 0)
-        PyThread_release_lock(self->rlock_lock);
+    /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
+       in rlock_new() */
+    if (self->rlock_lock != NULL) {
+        /* Unlock the lock so it's safe to free it */
+        if (self->rlock_count > 0)
+            PyThread_release_lock(self->rlock_lock);
 
-    PyThread_free_lock(self->rlock_lock);
+        PyThread_free_lock(self->rlock_lock);
+    }
     Py_TYPE(self)->tp_free(self);
 }
 
@@ -452,15 +455,16 @@
 
     self = (rlockobject *) type->tp_alloc(type, 0);
     if (self != NULL) {
+        self->in_weakreflist = NULL;
+        self->rlock_owner = 0;
+        self->rlock_count = 0;
+
         self->rlock_lock = PyThread_allocate_lock();
         if (self->rlock_lock == NULL) {
-            type->tp_free(self);
+            Py_DECREF(self);
             PyErr_SetString(ThreadError, "can't allocate lock");
             return NULL;
         }
-        self->in_weakreflist = NULL;
-        self->rlock_owner = 0;
-        self->rlock_count = 0;
     }
 
     return (PyObject *) self;