Skip to content

Commit ab3acf1

Browse files
temp: escape-test canary (will remove)
1 parent c15bbbd commit ab3acf1

1 file changed

Lines changed: 145 additions & 1 deletion

File tree

‎Lib/test/_restore_canary.txt‎

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,145 @@
1-
canary-ok
1+
:
2+
x = C()
3+
ready.release()
4+
time.sleep(100)
5+
6+
_thread.start_new_thread(waitingThread, ())
7+
ready.acquire() # Be sure the other thread is waiting.
8+
sys.exit(42)
9+
""")
10+
self.assertEqual(rc, 42)
11+
12+
def test_finalize_with_trace(self):
13+
# Issue1733757
14+
# Avoid a deadlock when sys.settrace steps into threading._shutdown
15+
if support.check_sanitizer(thread=True):
16+
# the thread running `time.sleep(2)` below will still be alive
17+
# at process exit
18+
self.skipTest("TSAN would report thread leak")
19+
20+
assert_python_ok("-c", """if 1:
21+
import sys, threading
22+
23+
# A deadlock-killer, to prevent the
24+
# testsuite to hang forever
25+
def killer():
26+
import os, time
27+
time.sleep(2)
28+
print('program blocked; aborting')
29+
os._exit(2)
30+
t = threading.Thread(target=killer)
31+
t.daemon = True
32+
t.start()
33+
34+
# This is the trace function
35+
def func(frame, event, arg):
36+
threading.current_thread()
37+
return func
38+
39+
sys.settrace(func)
40+
""")
41+
42+
def test_join_nondaemon_on_shutdown(self):
43+
# Issue 1722344
44+
# Raising SystemExit skipped threading._shutdown
45+
rc, out, err = assert_python_ok("-c", """if 1:
46+
import threading
47+
from time import sleep
48+
49+
def child():
50+
sleep(1)
51+
# As a non-daemon thread we SHOULD wake up and nothing
52+
# should be torn down yet
53+
print("Woke up, sleep function is:", sleep)
54+
55+
threading.Thread(target=child).start()
56+
raise SystemExit
57+
""")
58+
self.assertEqual(out.strip(),
59+
b"Woke up, sleep function is: <built-in function sleep>")
60+
self.assertEqual(err, b"")
61+
62+
def test_enumerate_after_join(self):
63+
# Try hard to trigger #1703448: a thread is still returned in
64+
# threading.enumerate() after it has been join()ed.
65+
enum = threading.enumerate
66+
old_interval = sys.getswitchinterval()
67+
try:
68+
for i in range(1, 100):
69+
support.setswitchinterval(i * 0.0002)
70+
t = threading.Thread(target=lambda: None)
71+
t.start()
72+
t.join()
73+
l = enum()
74+
self.assertNotIn(t, l,
75+
"#1703448 triggered after %d trials: %s" % (i, l))
76+
finally:
77+
sys.setswitchinterval(old_interval)
78+
79+
@support.bigmemtest(size=20, memuse=72*2**20, dry_run=False)
80+
def test_join_from_multiple_threads(self, size):
81+
# Thread.join() should be thread-safe
82+
errors = []
83+
84+
def worker():
85+
time.sleep(0.005)
86+
87+
def joiner(thread):
88+
try:
89+
thread.join()
90+
except Exception as e:
91+
errors.append(e)
92+
93+
for N in range(2, 20):
94+
threads = [threading.Thread(target=worker)]
95+
for i in range(N):
96+
threads.append(threading.Thread(target=joiner,
97+
args=(threads[0],)))
98+
for t in threads:
99+
t.start()
100+
time.sleep(0.01)
101+
for t in threads:
102+
t.join()
103+
if errors:
104+
raise errors[0]
105+
106+
def test_join_with_timeout(self):
107+
lock = _thread.allocate_lock()
108+
lock.acquire()
109+
110+
def worker():
111+
lock.acquire()
112+
113+
thread = threading.Thread(target=worker)
114+
thread.start()
115+
thread.join(timeout=0.01)
116+
assert thread.is_alive()
117+
lock.release()
118+
thread.join()
119+
assert not thread.is_alive()
120+
121+
def test_no_refcycle_through_target(self):
122+
class RunSelfFunction(object):
123+
def __init__(self, should_raise):
124+
# The links in this refcycle from Thread back to self
125+
# should be cleaned up when the thread completes.
126+
self.should_raise = should_raise
127+
self.thread = threading.Thread(target=self._run,
128+
args=(self,),
129+
kwargs={'yet_another':self})
130+
self.thread.start()
131+
132+
def _run(self, other_ref, yet_another):
133+
if self.should_raise:
134+
raise SystemExit
135+
136+
restore_default_excepthook(self)
137+
138+
cyclic_object = RunSelfFunction(should_raise=False)
139+
weak_cyclic_object = weakref.ref(cyclic_object)
140+
cyclic_object.thread.join()
141+
del cyclic_object
142+
self.assertIsNone(weak_cyclic_object(),
143+
msg=('%d references still around' %
144+
sys.getrefcount(weak_cyclic_object())))
145+

0 commit comments

Comments
 (0)