[pypy-commit] pypy py3.5-set-sentinel: release the sentinel lock before the thread dies
plan_rich
pypy.commits at gmail.com
Fri Sep 30 10:02:54 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-set-sentinel
Changeset: r87473:aa01e511c9e8
Date: 2016-09-30 16:02 +0200
http://bitbucket.org/pypy/pypy/changeset/aa01e511c9e8/
Log: release the sentinel lock before the thread dies
diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py
--- a/pypy/module/thread/os_lock.py
+++ b/pypy/module/thread/os_lock.py
@@ -3,6 +3,7 @@
"""
import time
+import weakref
from rpython.rlib import rthread
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.baseobjspace import W_Root
@@ -10,6 +11,7 @@
from pypy.interpreter.typedef import TypeDef, make_weakref_descr
from pypy.interpreter.error import oefmt
from rpython.rlib.rarithmetic import r_longlong, ovfcheck, ovfcheck_float_to_longlong
+from rpython.rlib.rthread import ThreadLocalReference
# Force the declaration of the type 'thread.LockType' for RPython
#import pypy.module.thread.rpython.exttable
@@ -19,6 +21,7 @@
RPY_LOCK_FAILURE, RPY_LOCK_ACQUIRED, RPY_LOCK_INTR = range(3)
+
def parse_acquire_args(space, blocking, timeout):
if not blocking and timeout != -1.0:
raise oefmt(space.w_ValueError,
@@ -144,15 +147,24 @@
See LockType.__doc__ for information about locks."""
return space.wrap(Lock(space))
-def set_sentinel(space):
+tlref_sentinel_lock = ThreadLocalReference(Lock)
+
+def _set_sentinel(space):
"""_set_sentinel() -> lock
Set a sentinel lock that will be released when the current thread
state is finalized (after it is untied from the interpreter).
This is a private API for the threading module."""
- lock = allocate_lock(space)
- return lock
+ # see issue 18808. We need to release this lock just before exiting
+ # the any thread!
+ lock = Lock(space)
+ # create a weak reference to the lock object and set it
+ # pass save it as a thread local reference
+ # see os_thread.py just before gc_thread_die
+ tlref_sentinel_lock.set(lock)
+ #
+ return space.wrap(lock)
class W_RLock(W_Root):
def __init__(self, space):
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -7,6 +7,7 @@
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import unwrap_spec, Arguments
+from pypy.module.thread.os_lock import tlref_sentinel_lock
# Here are the steps performed to start a new thread:
#
@@ -102,6 +103,12 @@
os.write(STDERR, "\n")
except OSError:
pass
+ # TODO move after rthread.gc_thread_die()?
+ lock = tlref_sentinel_lock.get()
+ if lock and lock.descr_lock_locked(space):
+ lock.descr_lock_release(space)
+ tlref_sentinel_lock.set(None)
+ #
bootstrapper.nbthreads -= 1
rthread.gc_thread_die()
bootstrap = staticmethod(bootstrap)
More information about the pypy-commit
mailing list