@@ -23,6 +23,7 @@ typedef struct {
2323 PyObject_HEAD
2424 PyThread_type_lock lock_lock ;
2525 PyObject * in_weakreflist ;
26+ char locked ; /* for sanity checking */
2627} lockobject ;
2728
2829static void
@@ -32,9 +33,8 @@ lock_dealloc(lockobject *self)
3233 PyObject_ClearWeakRefs ((PyObject * ) self );
3334 if (self -> lock_lock != NULL ) {
3435 /* Unlock the lock so it's safe to free it */
35- PyThread_acquire_lock (self -> lock_lock , 0 );
36- PyThread_release_lock (self -> lock_lock );
37-
36+ if (self -> locked )
37+ PyThread_release_lock (self -> lock_lock );
3838 PyThread_free_lock (self -> lock_lock );
3939 }
4040 PyObject_Del (self );
@@ -62,9 +62,13 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds)
6262
6363
6464 do {
65- Py_BEGIN_ALLOW_THREADS
66- r = PyThread_acquire_lock_timed (lock , microseconds , 1 );
67- Py_END_ALLOW_THREADS
65+ /* first a simple non-blocking try without releasing the GIL */
66+ r = PyThread_acquire_lock_timed (lock , 0 , 0 );
67+ if (r == PY_LOCK_FAILURE && microseconds != 0 ) {
68+ Py_BEGIN_ALLOW_THREADS
69+ r = PyThread_acquire_lock_timed (lock , microseconds , 1 );
70+ Py_END_ALLOW_THREADS
71+ }
6872
6973 if (r == PY_LOCK_INTR ) {
7074 /* Run signal handlers if we were interrupted. Propagate
@@ -135,6 +139,8 @@ lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
135139 return NULL ;
136140 }
137141
142+ if (r == PY_LOCK_ACQUIRED )
143+ self -> locked = 1 ;
138144 return PyBool_FromLong (r == PY_LOCK_ACQUIRED );
139145}
140146
@@ -153,13 +159,13 @@ static PyObject *
153159lock_PyThread_release_lock (lockobject * self )
154160{
155161 /* Sanity check: the lock must be locked */
156- if (PyThread_acquire_lock (self -> lock_lock , 0 )) {
157- PyThread_release_lock (self -> lock_lock );
162+ if (!self -> locked ) {
158163 PyErr_SetString (ThreadError , "release unlocked lock" );
159164 return NULL ;
160165 }
161166
162167 PyThread_release_lock (self -> lock_lock );
168+ self -> locked = 0 ;
163169 Py_INCREF (Py_None );
164170 return Py_None ;
165171}
@@ -175,11 +181,7 @@ but it needn't be locked by the same thread that unlocks it.");
175181static PyObject *
176182lock_locked_lock (lockobject * self )
177183{
178- if (PyThread_acquire_lock (self -> lock_lock , 0 )) {
179- PyThread_release_lock (self -> lock_lock );
180- return PyBool_FromLong (0L );
181- }
182- return PyBool_FromLong (1L );
184+ return PyBool_FromLong ((long )self -> locked );
183185}
184186
185187PyDoc_STRVAR (locked_doc ,
@@ -313,14 +315,7 @@ rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
313315 self -> rlock_count = count ;
314316 Py_RETURN_TRUE ;
315317 }
316-
317- if (self -> rlock_count > 0 ||
318- !PyThread_acquire_lock (self -> rlock_lock , 0 )) {
319- if (microseconds == 0 ) {
320- Py_RETURN_FALSE ;
321- }
322- r = acquire_timed (self -> rlock_lock , microseconds );
323- }
318+ r = acquire_timed (self -> rlock_lock , microseconds );
324319 if (r == PY_LOCK_ACQUIRED ) {
325320 assert (self -> rlock_count == 0 );
326321 self -> rlock_owner = tid ;
@@ -548,6 +543,7 @@ newlockobject(void)
548543 if (self == NULL )
549544 return NULL ;
550545 self -> lock_lock = PyThread_allocate_lock ();
546+ self -> locked = 0 ;
551547 self -> in_weakreflist = NULL ;
552548 if (self -> lock_lock == NULL ) {
553549 Py_DECREF (self );
0 commit comments