@@ -44,6 +44,7 @@ class Expectations(components.Capabilities):
4444 def __init__ (self , sock ):
4545 if sock == "stdio" :
4646 log .info ("Connecting to client over stdio..." , self )
47+ self .using_stdio = True
4748 stream = messaging .JsonIOStream .from_stdio ()
4849 # Make sure that nothing else tries to interfere with the stdio streams
4950 # that are going to be used for DAP communication from now on.
@@ -52,6 +53,7 @@ def __init__(self, sock):
5253 sys .stdout = stdout = open (os .devnull , "w" )
5354 atexit .register (stdout .close )
5455 else :
56+ self .using_stdio = False
5557 stream = messaging .JsonIOStream .from_socket (sock )
5658
5759 with sessions .Session () as session :
@@ -69,6 +71,11 @@ def __init__(self, sock):
6971 """The "launch" or "attach" request as received from the client.
7072 """
7173
74+ self .restart_requested = False
75+ """Whether the client requested the debug adapter to be automatically
76+ restarted via "restart":true in the start request.
77+ """
78+
7279 self ._initialize_request = None
7380 """The "initialize" request as received from the client, to propagate to the
7481 server later."""
@@ -471,6 +478,7 @@ def attach_request(self, request):
471478 host = listen ("host" , "127.0.0.1" )
472479 port = listen ("port" , int )
473480 adapter .access_token = None
481+ self .restart_requested = request ("restart" , False )
474482 host , port = servers .serve (host , port )
475483 else :
476484 if not servers .is_serving ():
@@ -651,6 +659,10 @@ def debugpySystemInfo_request(self, request):
651659
652660 @message_handler
653661 def terminate_request (self , request ):
662+ # If user specifically requests to terminate, it means that they don't want
663+ # debug session auto-restart kicking in.
664+ self .restart_requested = False
665+
654666 if self ._forward_terminate_request :
655667 # According to the spec, terminate should try to do a gracefull shutdown.
656668 # We do this in the server by interrupting the main thread with a Ctrl+C.
@@ -665,11 +677,29 @@ def terminate_request(self, request):
665677
666678 @message_handler
667679 def disconnect_request (self , request ):
680+ # If user specifically requests to disconnect, it means that they don't want
681+ # debug session auto-restart kicking in.
682+ self .restart_requested = False
683+
668684 terminate_debuggee = request ("terminateDebuggee" , bool , optional = True )
669685 if terminate_debuggee == ():
670686 terminate_debuggee = None
671687 self .session .finalize ('client requested "disconnect"' , terminate_debuggee )
672- return {}
688+ request .respond ({})
689+
690+ if self .using_stdio :
691+ # There's no way for the client to reconnect to this adapter once it disconnects
692+ # from this session, so close any remaining server connections.
693+ servers .stop_serving ()
694+ log .info ("{0} disconnected from stdio; closing remaining server connections." , self )
695+ for conn in servers .connections ():
696+ try :
697+ conn .channel .close ()
698+ except Exception :
699+ log .swallow_exception ()
700+
701+ def disconnect (self ):
702+ super ().disconnect ()
673703
674704 def notify_of_subprocess (self , conn ):
675705 log .info ("{1} is a subprocess of {0}." , self , conn )
@@ -689,7 +719,7 @@ def notify_of_subprocess(self, conn):
689719 self .known_subprocesses .add (conn )
690720 self .session .notify_changed ()
691721
692- for key in "processId" , "listen" , "preLaunchTask" , "postDebugTask" , "request" :
722+ for key in "processId" , "listen" , "preLaunchTask" , "postDebugTask" , "request" , "restart" :
693723 body .pop (key , None )
694724
695725 body ["name" ] = "Subprocess {0}" .format (conn .pid )
0 commit comments