<s> """<STR_LIT>""" <EOL> import subprocess <EOL> import tornado . ioloop <EOL> import time <EOL> import fcntl <EOL> import functools <EOL> import os <EOL> class GenericSubprocess ( object ) : <EOL> def __init__ ( self , timeout = - <NUM_LIT:1> , ** popen_args ) : <EOL> self . args = dict ( ) <EOL> self . args [ "<STR_LIT>" ] = subprocess . PIPE <EOL> self . args [ "<STR_LIT>" ] = subprocess . PIPE <EOL> self . args [ "<STR_LIT>" ] = True <EOL> self . args . update ( popen_args ) <EOL> self . ioloop = None <EOL> self . expiration = None <EOL> self . pipe = None <EOL> self . timeout = timeout <EOL> self . streams = [ ] <EOL> self . has_timed_out = False <EOL> def start ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . pipe is not None : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> self . ioloop = tornado . ioloop . IOLoop . instance ( ) <EOL> if self . timeout > <NUM_LIT:0> : <EOL> self . expiration = self . ioloop . add_timeout ( time . time ( ) + self . timeout , self . on_timeout ) <EOL> self . pipe = subprocess . Popen ( ** self . args ) <EOL> self . streams = [ ( self . pipe . stdout . fileno ( ) , [ ] ) , <EOL> ( self . pipe . stderr . fileno ( ) , [ ] ) ] <EOL> for fd , d in self . streams : <EOL> flags = fcntl . fcntl ( fd , fcntl . F_GETFL ) | os . O_NDELAY <EOL> fcntl . fcntl ( fd , fcntl . F_SETFL , flags ) <EOL> self . ioloop . add_handler ( fd , <EOL> self . stat , <EOL> self . ioloop . READ | self . ioloop . ERROR ) <EOL> def on_timeout ( self ) : <EOL> self . has_timed_out = True <EOL> self . cancel ( ) <EOL> def cancel ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . pipe . kill ( ) <EOL> except : <EOL> pass <EOL> def stat ( self , * args ) : <EOL> '''<STR_LIT>''' <EOL> self . pipe . poll ( ) <EOL> if self . pipe . returncode is not None : <EOL> '''<STR_LIT>''' <EOL> if self . expiration is not None : <EOL> self . ioloop . remove_timeout ( self . expiration ) <EOL> for fd , dest in self . streams : <EOL> self . ioloop . remove_handler ( fd ) <EOL> '''<STR_LIT>''' <EOL> self . ioloop . add_callback ( self . on_finish ) <EOL> for fd , dest in self . streams : <EOL> while True : <EOL> try : <EOL> data = os . read ( fd , <NUM_LIT> ) <EOL> if len ( data ) == <NUM_LIT:0> : <EOL> break <EOL> dest . extend ( [ data ] ) <EOL> except : <EOL> break <EOL> @ property <EOL> def stdout ( self ) : <EOL> return self . get_output ( <NUM_LIT:0> ) <EOL> @ property <EOL> def stderr ( self ) : <EOL> return self . get_output ( <NUM_LIT:1> ) <EOL> @ property <EOL> def status ( self ) : <EOL> return self . pipe . returncode <EOL> def get_output ( self , index ) : <EOL> return b"<STR_LIT>" . join ( self . streams [ index ] [ <NUM_LIT:1> ] ) <EOL> def on_finish ( self ) : <EOL> raise NotImplemented ( ) <EOL> class Subprocess ( GenericSubprocess ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , callback , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> self . callback = callback <EOL> self . done_callback = False <EOL> GenericSubprocess . __init__ ( self , * args , ** kwargs ) <EOL> def on_finish ( self ) : <EOL> if not self . done_callback : <EOL> self . done_callback = True <EOL> '''<STR_LIT>''' <EOL> self . ioloop . add_callback ( functools . partial ( self . callback , self . status , self . stdout , self . stderr , self . has_timed_out ) ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> ioloop = tornado . ioloop . IOLoop . instance ( ) <EOL> def print_timeout ( status , stdout , stderr , has_timed_out ) : <EOL> assert ( status != <NUM_LIT:0> ) <EOL> assert ( has_timed_out ) <EOL> print ( "<STR_LIT>" , repr ( status ) , "<STR_LIT>" , repr ( stdout ) , "<STR_LIT>" , repr ( stderr ) , "<STR_LIT>" , repr ( has_timed_out ) ) <EOL> def print_ok ( status , stdout , stderr , has_timed_out ) : <EOL> assert ( status == <NUM_LIT:0> ) <EOL> assert ( not has_timed_out ) <EOL> print ( "<STR_LIT>" , repr ( status ) , "<STR_LIT>" , repr ( stdout ) , "<STR_LIT>" , repr ( stderr ) , "<STR_LIT>" , repr ( has_timed_out ) ) <EOL> def print_error ( status , stdout , stderr , has_timed_out ) : <EOL> assert ( status != <NUM_LIT:0> ) <EOL> assert ( not has_timed_out ) <EOL> print ( "<STR_LIT>" , repr ( status ) , "<STR_LIT>" , repr ( stdout ) , "<STR_LIT>" , repr ( stderr ) , "<STR_LIT>" , repr ( has_timed_out ) ) <EOL> def stop_test ( ) : <EOL> ioloop . stop ( ) <EOL> t1 = Subprocess ( print_timeout , timeout = <NUM_LIT:3> , args = [ "<STR_LIT>" , "<STR_LIT:5>" ] ) <EOL> t2 = Subprocess ( print_ok , timeout = <NUM_LIT:3> , args = [ "<STR_LIT>" , "<STR_LIT:1>" ] ) <EOL> t3 = Subprocess ( print_ok , timeout = <NUM_LIT:3> , args = [ "<STR_LIT>" , "<STR_LIT:1>" ] ) <EOL> t4 = Subprocess ( print_error , timeout = <NUM_LIT:3> , args = [ "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> t1 . start ( ) <EOL> t2 . start ( ) <EOL> try : <EOL> t3 . start ( ) <EOL> assert ( false ) <EOL> except : <EOL> print ( "<STR_LIT:OK>" ) <EOL> t4 . start ( ) <EOL> ioloop . add_timeout ( time . time ( ) + <NUM_LIT:10> , stop_test ) <EOL> ioloop . start ( ) </s>
