4646CONNECTION_TIMEOUT = 20.
4747
4848_mmap_counter = itertools .count ()
49+ _MAX_PIPE_ATTEMPTS = 100
4950
5051default_family = 'AF_INET'
5152families = ['AF_INET' ]
@@ -78,8 +79,8 @@ def arbitrary_address(family):
7879 elif family == 'AF_UNIX' :
7980 return tempfile .mktemp (prefix = 'sock-' , dir = util .get_temp_dir ())
8081 elif family == 'AF_PIPE' :
81- return tempfile . mktemp ( prefix = r'\\.\pipe\pyc-%d-%d-' %
82- (os .getpid (), next (_mmap_counter )), dir = "" )
82+ return ( r'\\.\pipe\pyc-%d-%d-%s ' %
83+ (os .getpid (), next (_mmap_counter ), os . urandom ( 8 ). hex ()) )
8384 else :
8485 raise ValueError ('unrecognized family' )
8586
@@ -472,17 +473,29 @@ class Listener(object):
472473 def __init__ (self , address = None , family = None , backlog = 1 , authkey = None ):
473474 family = family or (address and address_type (address )) \
474475 or default_family
475- address = address or arbitrary_address (family )
476-
477476 _validate_family (family )
477+ if authkey is not None and not isinstance (authkey , bytes ):
478+ raise TypeError ('authkey should be a byte string' )
479+
478480 if family == 'AF_PIPE' :
479- self ._listener = PipeListener (address , backlog )
481+ if address :
482+ self ._listener = PipeListener (address , backlog )
483+ else :
484+ for attempts in itertools .count ():
485+ address = arbitrary_address (family )
486+ try :
487+ self ._listener = PipeListener (address , backlog )
488+ break
489+ except OSError as e :
490+ if attempts >= _MAX_PIPE_ATTEMPTS :
491+ raise
492+ if e .winerror not in (_winapi .ERROR_PIPE_BUSY ,
493+ _winapi .ERROR_ACCESS_DENIED ):
494+ raise
480495 else :
496+ address = address or arbitrary_address (family )
481497 self ._listener = SocketListener (address , family , backlog )
482498
483- if authkey is not None and not isinstance (authkey , bytes ):
484- raise TypeError ('authkey should be a byte string' )
485-
486499 self ._authkey = authkey
487500
488501 def accept (self ):
@@ -570,7 +583,6 @@ def Pipe(duplex=True):
570583 '''
571584 Returns pair of connection objects at either end of a pipe
572585 '''
573- address = arbitrary_address ('AF_PIPE' )
574586 if duplex :
575587 openmode = _winapi .PIPE_ACCESS_DUPLEX
576588 access = _winapi .GENERIC_READ | _winapi .GENERIC_WRITE
@@ -580,15 +592,25 @@ def Pipe(duplex=True):
580592 access = _winapi .GENERIC_WRITE
581593 obsize , ibsize = 0 , BUFSIZE
582594
583- h1 = _winapi .CreateNamedPipe (
584- address , openmode | _winapi .FILE_FLAG_OVERLAPPED |
585- _winapi .FILE_FLAG_FIRST_PIPE_INSTANCE ,
586- _winapi .PIPE_TYPE_MESSAGE | _winapi .PIPE_READMODE_MESSAGE |
587- _winapi .PIPE_WAIT ,
588- 1 , obsize , ibsize , _winapi .NMPWAIT_WAIT_FOREVER ,
589- # default security descriptor: the handle cannot be inherited
590- _winapi .NULL
591- )
595+ for attempts in itertools .count ():
596+ address = arbitrary_address ('AF_PIPE' )
597+ try :
598+ h1 = _winapi .CreateNamedPipe (
599+ address , openmode | _winapi .FILE_FLAG_OVERLAPPED |
600+ _winapi .FILE_FLAG_FIRST_PIPE_INSTANCE ,
601+ _winapi .PIPE_TYPE_MESSAGE | _winapi .PIPE_READMODE_MESSAGE |
602+ _winapi .PIPE_WAIT ,
603+ 1 , obsize , ibsize , _winapi .NMPWAIT_WAIT_FOREVER ,
604+ # default security descriptor: the handle cannot be inherited
605+ _winapi .NULL
606+ )
607+ break
608+ except OSError as e :
609+ if attempts >= _MAX_PIPE_ATTEMPTS :
610+ raise
611+ if e .winerror not in (_winapi .ERROR_PIPE_BUSY ,
612+ _winapi .ERROR_ACCESS_DENIED ):
613+ raise
592614 h2 = _winapi .CreateFile (
593615 address , access , 0 , _winapi .NULL , _winapi .OPEN_EXISTING ,
594616 _winapi .FILE_FLAG_OVERLAPPED , _winapi .NULL
0 commit comments