blob: 29eab1a7b1dfbe30c0850bab9c2256900dccb1cb [file] [log] [blame]
Tim Petersaa222232001-05-22 09:34:27 +00001# This is a variant of the very old (early 90's) file
2# Demo/threads/bug.py. It simply provokes a number of threads into
3# trying to import the same module "at the same time".
4# There are no pleasant failure modes -- most likely is that Python
5# complains several times about module random having no attribute
6# randrange, and then Python hangs.
7
Georg Brandl2067bfd2008-05-25 13:05:15 +00008import _thread as thread
Georg Brandl89fad142010-03-14 10:23:39 +00009import unittest
Benjamin Petersone549ead2009-03-28 21:42:05 +000010from test.support import verbose, TestFailed
Tim Petersaa222232001-05-22 09:34:27 +000011
12critical_section = thread.allocate_lock()
13done = thread.allocate_lock()
14
15def task():
16 global N, critical_section, done
17 import random
18 x = random.randrange(1, 3)
19 critical_section.acquire()
20 N -= 1
Tim Peters20882dd2002-02-16 07:26:27 +000021 # Must release critical_section before releasing done, else the main
22 # thread can exit and set critical_section to None as part of global
23 # teardown; then critical_section.release() raises AttributeError.
24 finished = N == 0
Tim Petersaa222232001-05-22 09:34:27 +000025 critical_section.release()
Tim Peters20882dd2002-02-16 07:26:27 +000026 if finished:
27 done.release()
Tim Petersaa222232001-05-22 09:34:27 +000028
Thomas Wouters477c8d52006-05-27 19:21:47 +000029def test_import_hangers():
30 import sys
31 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000032 print("testing import hangers ...", end=' ')
Thomas Wouters477c8d52006-05-27 19:21:47 +000033
Thomas Wouters0e3f5912006-08-11 14:57:12 +000034 import test.threaded_import_hangers
Thomas Wouters477c8d52006-05-27 19:21:47 +000035 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000036 if test.threaded_import_hangers.errors:
37 raise TestFailed(test.threaded_import_hangers.errors)
Thomas Wouters477c8d52006-05-27 19:21:47 +000038 elif verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000039 print("OK.")
Thomas Wouters477c8d52006-05-27 19:21:47 +000040 finally:
41 # In case this test is run again, make sure the helper module
42 # gets loaded from scratch again.
43 del sys.modules['test.threaded_import_hangers']
44
Tim Petersd9742212001-05-22 18:28:25 +000045# Tricky: When regrtest imports this module, the thread running regrtest
46# grabs the import lock and won't let go of it until this module returns.
47# All other threads attempting an import hang for the duration. Since
48# this test spawns threads that do little *but* import, we can't do that
49# successfully until after this module finishes importing and regrtest
50# regains control. To make this work, a special case was added to
51# regrtest to invoke a module's "test_main" function (if any) after
52# importing it.
Tim Petersaa222232001-05-22 09:34:27 +000053
Tim Petersd9742212001-05-22 18:28:25 +000054def test_main(): # magic name! see above
Tim Petersaa222232001-05-22 09:34:27 +000055 global N, done
Tim Peters69232342001-08-30 05:16:13 +000056
57 import imp
58 if imp.lock_held():
59 # This triggers on, e.g., from test import autotest.
Benjamin Petersone549ead2009-03-28 21:42:05 +000060 raise unittest.SkipTest("can't run when import lock is held")
Tim Peters69232342001-08-30 05:16:13 +000061
Tim Petersaa222232001-05-22 09:34:27 +000062 done.acquire()
Tim Petersd9742212001-05-22 18:28:25 +000063 for N in (20, 50) * 3:
64 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000065 print("Trying", N, "threads ...", end=' ')
Tim Petersaa222232001-05-22 09:34:27 +000066 for i in range(N):
67 thread.start_new_thread(task, ())
68 done.acquire()
Tim Petersd9742212001-05-22 18:28:25 +000069 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000070 print("OK.")
Michael W. Hudsonfcc09bb2004-08-03 10:45:59 +000071 done.release()
Tim Petersaa222232001-05-22 09:34:27 +000072
Thomas Wouters477c8d52006-05-27 19:21:47 +000073 test_import_hangers()
74
Tim Petersd9742212001-05-22 18:28:25 +000075if __name__ == "__main__":
76 test_main()