[3.6] bpo-31234: Add test.support.wait_threads_exit() (GH-3578) (GH-7… · python/cpython@5dbb48a (original) (raw)

`@@ -59,12 +59,13 @@ def task(self, ident):

`

59

59

`self.done_mutex.release()

`

60

60

``

61

61

`def test_starting_threads(self):

`

62

``

`-

Basic test for thread creation.

`

63

``

`-

for i in range(NUMTASKS):

`

64

``

`-

self.newtask()

`

65

``

`-

verbose_print("waiting for tasks to complete...")

`

66

``

`-

self.done_mutex.acquire()

`

67

``

`-

verbose_print("all tasks done")

`

``

62

`+

with support.wait_threads_exit():

`

``

63

`+

Basic test for thread creation.

`

``

64

`+

for i in range(NUMTASKS):

`

``

65

`+

self.newtask()

`

``

66

`+

verbose_print("waiting for tasks to complete...")

`

``

67

`+

self.done_mutex.acquire()

`

``

68

`+

verbose_print("all tasks done")

`

68

69

``

69

70

`def test_stack_size(self):

`

70

71

`# Various stack size tests.

`

`@@ -94,12 +95,13 @@ def test_nt_and_posix_stack_size(self):

`

94

95

`verbose_print("trying stack_size = (%d)" % tss)

`

95

96

`self.next_ident = 0

`

96

97

`self.created = 0

`

97

``

`-

for i in range(NUMTASKS):

`

98

``

`-

self.newtask()

`

``

98

`+

with support.wait_threads_exit():

`

``

99

`+

for i in range(NUMTASKS):

`

``

100

`+

self.newtask()

`

99

101

``

100

``

`-

verbose_print("waiting for all tasks to complete")

`

101

``

`-

self.done_mutex.acquire()

`

102

``

`-

verbose_print("all tasks done")

`

``

102

`+

verbose_print("waiting for all tasks to complete")

`

``

103

`+

self.done_mutex.acquire()

`

``

104

`+

verbose_print("all tasks done")

`

103

105

``

104

106

`thread.stack_size(0)

`

105

107

``

`@@ -109,25 +111,28 @@ def test__count(self):

`

109

111

`mut = thread.allocate_lock()

`

110

112

`mut.acquire()

`

111

113

`started = []

`

``

114

+

112

115

`def task():

`

113

116

`started.append(None)

`

114

117

`mut.acquire()

`

115

118

`mut.release()

`

116

``

`-

thread.start_new_thread(task, ())

`

117

``

`-

while not started:

`

118

``

`-

time.sleep(POLL_SLEEP)

`

119

``

`-

self.assertEqual(thread._count(), orig + 1)

`

120

``

`-

Allow the task to finish.

`

121

``

`-

mut.release()

`

122

``

`-

The only reliable way to be sure that the thread ended from the

`

123

``

`-

interpreter's point of view is to wait for the function object to be

`

124

``

`-

destroyed.

`

125

``

`-

done = []

`

126

``

`-

wr = weakref.ref(task, lambda _: done.append(None))

`

127

``

`-

del task

`

128

``

`-

while not done:

`

129

``

`-

time.sleep(POLL_SLEEP)

`

130

``

`-

self.assertEqual(thread._count(), orig)

`

``

119

+

``

120

`+

with support.wait_threads_exit():

`

``

121

`+

thread.start_new_thread(task, ())

`

``

122

`+

while not started:

`

``

123

`+

time.sleep(POLL_SLEEP)

`

``

124

`+

self.assertEqual(thread._count(), orig + 1)

`

``

125

`+

Allow the task to finish.

`

``

126

`+

mut.release()

`

``

127

`+

The only reliable way to be sure that the thread ended from the

`

``

128

`+

interpreter's point of view is to wait for the function object to be

`

``

129

`+

destroyed.

`

``

130

`+

done = []

`

``

131

`+

wr = weakref.ref(task, lambda _: done.append(None))

`

``

132

`+

del task

`

``

133

`+

while not done:

`

``

134

`+

time.sleep(POLL_SLEEP)

`

``

135

`+

self.assertEqual(thread._count(), orig)

`

131

136

``

132

137

`def test_save_exception_state_on_error(self):

`

133

138

`# See issue #14474

`

`@@ -140,16 +145,14 @@ def mywrite(self, *args):

`

140

145

`except ValueError:

`

141

146

`pass

`

142

147

`real_write(self, *args)

`

143

``

`-

c = thread._count()

`

144

148

`started = thread.allocate_lock()

`

145

149

`with support.captured_output("stderr") as stderr:

`

146

150

`real_write = stderr.write

`

147

151

`stderr.write = mywrite

`

148

152

`started.acquire()

`

149

``

`-

thread.start_new_thread(task, ())

`

150

``

`-

started.acquire()

`

151

``

`-

while thread._count() > c:

`

152

``

`-

time.sleep(POLL_SLEEP)

`

``

153

`+

with support.wait_threads_exit():

`

``

154

`+

thread.start_new_thread(task, ())

`

``

155

`+

started.acquire()

`

153

156

`self.assertIn("Traceback", stderr.getvalue())

`

154

157

``

155

158

``

`@@ -181,13 +184,14 @@ def enter(self):

`

181

184

`class BarrierTest(BasicThreadTest):

`

182

185

``

183

186

`def test_barrier(self):

`

184

``

`-

self.bar = Barrier(NUMTASKS)

`

185

``

`-

self.running = NUMTASKS

`

186

``

`-

for i in range(NUMTASKS):

`

187

``

`-

thread.start_new_thread(self.task2, (i,))

`

188

``

`-

verbose_print("waiting for tasks to end")

`

189

``

`-

self.done_mutex.acquire()

`

190

``

`-

verbose_print("tasks done")

`

``

187

`+

with support.wait_threads_exit():

`

``

188

`+

self.bar = Barrier(NUMTASKS)

`

``

189

`+

self.running = NUMTASKS

`

``

190

`+

for i in range(NUMTASKS):

`

``

191

`+

thread.start_new_thread(self.task2, (i,))

`

``

192

`+

verbose_print("waiting for tasks to end")

`

``

193

`+

self.done_mutex.acquire()

`

``

194

`+

verbose_print("tasks done")

`

191

195

``

192

196

`def task2(self, ident):

`

193

197

`for i in range(NUMTRIPS):

`

`@@ -225,11 +229,10 @@ def setUp(self):

`

225

229

`@unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork')

`

226

230

`@support.reap_threads

`

227

231

`def test_forkinthread(self):

`

228

``

`-

running = True

`

229

232

`status = "not set"

`

230

233

``

231

234

`def thread1():

`

232

``

`-

nonlocal running, status

`

``

235

`+

nonlocal status

`

233

236

``

234

237

`# fork in a thread

`

235

238

`pid = os.fork()

`

`@@ -244,13 +247,11 @@ def thread1():

`

244

247

`# parent

`

245

248

`os.close(self.write_fd)

`

246

249

`pid, status = os.waitpid(pid, 0)

`

247

``

`-

running = False

`

248

250

``

249

``

`-

thread.start_new_thread(thread1, ())

`

250

``

`-

self.assertEqual(os.read(self.read_fd, 2), b"OK",

`

251

``

`-

"Unable to fork() in thread")

`

252

``

`-

while running:

`

253

``

`-

time.sleep(POLL_SLEEP)

`

``

251

`+

with support.wait_threads_exit():

`

``

252

`+

thread.start_new_thread(thread1, ())

`

``

253

`+

self.assertEqual(os.read(self.read_fd, 2), b"OK",

`

``

254

`+

"Unable to fork() in thread")

`

254

255

`self.assertEqual(status, 0)

`

255

256

``

256

257

`def tearDown(self):

`