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())
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index d83d117..32656c9 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -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->rlock_lock = PyThread_allocate_lock();
- if (self->rlock_lock == NULL) {
- type->tp_free(self);
- PyErr_SetString(ThreadError, "can't allocate lock");
- return NULL;
- }
self->in_weakreflist = NULL;
self->rlock_owner = 0;
self->rlock_count = 0;
+
+ self->rlock_lock = PyThread_allocate_lock();
+ if (self->rlock_lock == NULL) {
+ Py_DECREF(self);
+ PyErr_SetString(ThreadError, "can't allocate lock");
+ return NULL;
+ }
}
return (PyObject *) self;