2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# This is a variant of the very old (early 90's) file
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# Demo/threads/bug.py.  It simply provokes a number of threads into
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# trying to import the same module "at the same time".
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# There are no pleasant failure modes -- most likely is that Python
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# complains several times about module random having no attribute
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# randrange, and then Python hangs.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import thread
							 | 
						
					
						
							
								
									
										
										
										
											2002-07-23 19:04:11 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from test.test_support import verbose, TestSkipped
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								critical_section = thread.allocate_lock()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								done = thread.allocate_lock()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								def task():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    global N, critical_section, done
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    import random
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    x = random.randrange(1, 3)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    critical_section.acquire()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    N -= 1
							 | 
						
					
						
							
								
									
										
										
										
											2002-02-16 07:26:27 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Must release critical_section before releasing done, else the main
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # thread can exit and set critical_section to None as part of global
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # teardown; then critical_section.release() raises AttributeError.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    finished = N == 0
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    critical_section.release()
							 | 
						
					
						
							
								
									
										
										
										
											2002-02-16 07:26:27 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if finished:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        done.release()
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 18:28:25 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# Tricky:  When regrtest imports this module, the thread running regrtest
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# grabs the import lock and won't let go of it until this module returns.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# All other threads attempting an import hang for the duration.  Since
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# this test spawns threads that do little *but* import, we can't do that
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# successfully until after this module finishes importing and regrtest
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# regains control.  To make this work, a special case was added to
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# regrtest to invoke a module's "test_main" function (if any) after
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# importing it.
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 18:28:25 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								def test_main():        # magic name!  see above
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    global N, done
							 | 
						
					
						
							
								
									
										
										
										
											2001-08-30 05:16:13 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    import imp
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if imp.lock_held():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # This triggers on, e.g., from test import autotest.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        raise TestSkipped("can't run when import lock is held")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    done.acquire()
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 18:28:25 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    for N in (20, 50) * 3:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if verbose:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            print "Trying", N, "threads ...",
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for i in range(N):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            thread.start_new_thread(task, ())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        done.acquire()
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 18:28:25 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if verbose:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            print "OK."
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 09:34:27 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2001-05-22 18:28:25 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								if __name__ == "__main__":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    test_main()
							 |