summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2013-11-05 14:10:19 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2013-11-05 14:10:19 (GMT)
commit357f5155dc74b691a683a571b1316ce8473c40d0 (patch)
tree9532e72c7c039e21f9b367663414222ec9b4c83a
parent85a12a8bebd20e86fa3931940d7e317fa392cfb8 (diff)
downloadcpython-357f5155dc74b691a683a571b1316ce8473c40d0.zip
cpython-357f5155dc74b691a683a571b1316ce8473c40d0.tar.gz
cpython-357f5155dc74b691a683a571b1316ce8473c40d0.tar.bz2
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())
-rw-r--r--Modules/_threadmodule.c24
1 files changed, 14 insertions, 10 deletions
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 @@ 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;