mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Everything is done inside the loader function so that no other names
 | 
						|
# are placed in the global namespace.  Before user code is executed,
 | 
						|
# even this name is unbound.
 | 
						|
def loader():
 | 
						|
    import sys, os, protocol, threading, time
 | 
						|
    import Remote
 | 
						|
 | 
						|
##  Use to debug the loading process itself:
 | 
						|
##    sys.stdout = open('c:\\windows\\desktop\\stdout.txt','a')
 | 
						|
##    sys.stderr = open('c:\\windows\\desktop\\stderr.txt','a')
 | 
						|
 | 
						|
    # Ensure that there is absolutely no pollution of the global
 | 
						|
    # namespace by deleting the global name of this function.
 | 
						|
    global loader
 | 
						|
    del loader
 | 
						|
 | 
						|
    # Connect to IDLE
 | 
						|
    try:
 | 
						|
        client = protocol.Client()
 | 
						|
    except protocol.connectionLost, cL:
 | 
						|
        print 'loader: Unable to connect to IDLE', cL
 | 
						|
        return
 | 
						|
 | 
						|
    # Connect to an ExecBinding object that needs our help.  If
 | 
						|
    # the user is starting multiple programs right now, we might get a
 | 
						|
    # different one than the one that started us.  Proving that's okay is
 | 
						|
    # left as an exercise to the reader.  (HINT:  Twelve, by the pigeonhole
 | 
						|
    # principle)
 | 
						|
    ExecBinding = client.getobject('ExecBinding')
 | 
						|
    if not ExecBinding:
 | 
						|
        print "loader: IDLE does not need me."
 | 
						|
        return
 | 
						|
 | 
						|
    # All of our input and output goes through ExecBinding.
 | 
						|
    sys.stdin  = Remote.pseudoIn( ExecBinding.readline )
 | 
						|
    sys.stdout = Remote.pseudoOut( ExecBinding.write.void, tag="stdout" )
 | 
						|
    sys.stderr = Remote.pseudoOut( ExecBinding.write.void, tag="stderr" )
 | 
						|
 | 
						|
    # Create a Remote object and start it running.
 | 
						|
    remote = Remote.Remote(globals(), ExecBinding)
 | 
						|
    rthread = threading.Thread(target=remote.mainloop)
 | 
						|
    rthread.setDaemon(1)
 | 
						|
    rthread.start()
 | 
						|
 | 
						|
    # Block until either the client or the user program stops
 | 
						|
    user = rthread.isAlive
 | 
						|
    while user and client.isAlive():
 | 
						|
        time.sleep(0.025)
 | 
						|
 | 
						|
        if not user():
 | 
						|
          user = hasattr(sys, "ready_to_exit") and sys.ready_to_exit
 | 
						|
          for t in threading.enumerate():
 | 
						|
            if not t.isDaemon() and t.isAlive() and t!=threading.currentThread():
 | 
						|
              user = t.isAlive
 | 
						|
              break
 | 
						|
 | 
						|
    # We need to make sure we actually exit, so that the user doesn't get
 | 
						|
    #   stuck with an invisible process.  We want to finalize C modules, so
 | 
						|
    #   we don't use os._exit(), but we don't call sys.exitfunc, which might
 | 
						|
    #   block forever.
 | 
						|
    del sys.exitfunc
 | 
						|
    sys.exit()
 | 
						|
 | 
						|
loader()
 |