Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Fix race in PyThread_release_lock that was leading to memory corruption and
deadlocks. The fix applies to POSIX systems where Python locks are implemented
with mutex and condition variable because POSIX semaphores are either not
provided, or are known to be broken. One particular example of such system is
macOS.
15 changes: 9 additions & 6 deletions Python/thread_pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,12 +430,15 @@ PyThread_free_lock(PyThread_type_lock lock)
(void) error; /* silence unused-but-set-variable warning */
dprintf(("PyThread_free_lock(%p) called\n", lock));

status = pthread_mutex_destroy( &thelock->mut );
CHECK_STATUS("pthread_mutex_destroy");

/* some pthread-like implementations tie the mutex to the cond
* and must have the cond destroyed first.
*/
status = pthread_cond_destroy( &thelock->lock_released );
CHECK_STATUS("pthread_cond_destroy");

status = pthread_mutex_destroy( &thelock->mut );
CHECK_STATUS("pthread_mutex_destroy");

free((void *)thelock);
}

Expand Down Expand Up @@ -497,12 +500,12 @@ PyThread_release_lock(PyThread_type_lock lock)

thelock->locked = 0;

status = pthread_mutex_unlock( &thelock->mut );
CHECK_STATUS("pthread_mutex_unlock[3]");

/* wake up someone (anyone, if any) waiting on the lock */
status = pthread_cond_signal( &thelock->lock_released );
CHECK_STATUS("pthread_cond_signal");

status = pthread_mutex_unlock( &thelock->mut );
CHECK_STATUS("pthread_mutex_unlock[3]");
}

#endif /* USE_SEMAPHORES */
Expand Down