@@ -143,6 +143,9 @@ def __init__(
143143 self .encoding = encoding
144144 self .reader_fds = {}
145145 base_dir = os .path .join (BASE_DIR , f"aexpect_{ self .a_id } " )
146+ self ._close_lockfile = os .path .join (
147+ BASE_DIR , f"aexpect_{ self .a_id } .lock"
148+ )
146149
147150 # Define filenames for communication with server
148151 utils_path .init_dir (base_dir )
@@ -431,27 +434,48 @@ def close(self, sig=signal.SIGKILL):
431434
432435 :param sig: The signal to send the process when attempting to kill it.
433436 """
434- if not self .closed :
435- self .kill (sig = sig )
436- # Wait for the server to exit
437- if not wait_for_lock (
438- self .lock_server_running_filename , timeout = 60
439- ):
440- LOG .warning (
441- "Failed to get lock, the aexpect_helper process "
442- "might be left behind. Proceeding anyway..."
443- )
444- # Call all cleanup routines
445- for hook in self .close_hooks :
446- hook (self )
447- # Close reader file descriptors
448- self ._close_reader_fds ()
449- self .reader_fds = {}
450- # Remove all used files
451- if "AEXPECT_DEBUG" not in os .environ :
452- shutil .rmtree (os .path .join (BASE_DIR , f"aexpect_{ self .a_id } " ))
453- self ._close_aexpect_helper ()
454- self .closed = True
437+ if self .closed :
438+ return
439+ lock = None
440+ try :
441+ try :
442+ lock = get_lock_fd (self ._close_lockfile , timeout = 60 )
443+ except FileNotFoundError :
444+ if not self .closed :
445+ raise
446+ if not self .closed :
447+ self .kill (sig = sig )
448+ # Wait for the server to exit
449+ if not wait_for_lock (
450+ self .lock_server_running_filename , timeout = 60
451+ ):
452+ LOG .warning (
453+ "Failed to get lock, the aexpect_helper "
454+ "process might be left behind. Proceeding "
455+ "anyway..."
456+ )
457+ # Call all cleanup routines
458+ for hook in self .close_hooks :
459+ hook (self )
460+ # Close reader file descriptors
461+ self ._close_reader_fds ()
462+ self .reader_fds = {}
463+ # Remove all used files
464+ if "AEXPECT_DEBUG" not in os .environ :
465+ shutil .rmtree (
466+ os .path .join (BASE_DIR , f"aexpect_{ self .a_id } " ),
467+ ignore_errors = True ,
468+ )
469+ self ._close_aexpect_helper ()
470+ self .closed = True
471+ finally :
472+ if lock is not None :
473+ try :
474+ unlock_fd (lock )
475+ os .unlink (self ._close_lockfile )
476+ except FileNotFoundError :
477+ # File already removed by other thread
478+ pass
455479
456480 def set_linesep (self , linesep ):
457481 """
0 commit comments