]> granicus.if.org Git - python/commitdiff
Issue #19437: Fix _threading.RLock constructor (rlock_new), call
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 5 Nov 2013 14:10:19 +0000 (15:10 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 5 Nov 2013 14:10:19 +0000 (15:10 +0100)
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())

Modules/_threadmodule.c

index d83d117636497c0316f57243df6b86bcf652b1df..32656c9ac588b46706bdda4eadbe22cf145cc960 100644 (file)
@@ -68,7 +68,7 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds)
             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 @@ typedef struct {
 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 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
     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;