@@ -34,18 +34,28 @@ def setup(self):
3434
3535    def  handle (self ):
3636        self .delegate .start ()
37+         # pylint: disable=no-member 
38+         self .SHUTDOWN_CALL ()
3739
3840
3941def  start_tcp_lang_server (bind_addr , port , check_parent_process , handler_class ):
4042    if  not  issubclass (handler_class , PythonLanguageServer ):
4143        raise  ValueError ('Handler class must be an instance of PythonLanguageServer' )
4244
45+     def  shutdown_server (* args ):
46+         # pylint: disable=unused-argument 
47+         log .debug ('Shutting down server' )
48+         # Shutdown call must be done on a thread, to prevent deadlocks 
49+         stop_thread  =  threading .Thread (target = server .shutdown )
50+         stop_thread .start ()
51+ 
4352    # Construct a custom wrapper class around the user's handler_class 
4453    wrapper_class  =  type (
4554        handler_class .__name__  +  'Handler' ,
4655        (_StreamHandlerWrapper ,),
4756        {'DELEGATE_CLASS' : partial (handler_class ,
48-                                    check_parent_process = check_parent_process )}
57+                                    check_parent_process = check_parent_process ),
58+          'SHUTDOWN_CALL' : shutdown_server }
4959    )
5060
5161    server  =  socketserver .TCPServer ((bind_addr , port ), wrapper_class )
@@ -78,6 +88,7 @@ def __init__(self, rx, tx, check_parent_process=False):
7888        self .workspace  =  None 
7989        self .config  =  None 
8090        self .root_uri  =  None 
91+         self .watching_thread  =  None 
8192        self .workspaces  =  {}
8293        self .uri_workspace_mapper  =  {}
8394
@@ -187,19 +198,18 @@ def m_initialize(self, processId=None, rootUri=None, rootPath=None, initializati
187198        self ._dispatchers  =  self ._hook ('pyls_dispatchers' )
188199        self ._hook ('pyls_initialize' )
189200
190-         if  self ._check_parent_process  and  processId  is  not   None :
201+         if  self ._check_parent_process  and  processId  is  not   None   and   self . watching_thread   is   None :
191202            def  watch_parent_process (pid ):
192203                # exit when the given pid is not alive 
193204                if  not  _utils .is_process_alive (pid ):
194205                    log .info ("parent process %s is not alive" , pid )
195206                    self .m_exit ()
196-                 log .debug ("parent process %s is still alive" , pid )
197-                 threading .Timer (PARENT_PROCESS_WATCH_INTERVAL , watch_parent_process , args = [pid ]).start ()
198- 
199-             watching_thread  =  threading .Thread (target = watch_parent_process , args = (processId ,))
200-             watching_thread .daemon  =  True 
201-             watching_thread .start ()
207+                 else :
208+                     threading .Timer (PARENT_PROCESS_WATCH_INTERVAL , watch_parent_process , args = [pid ]).start ()
202209
210+             self .watching_thread  =  threading .Thread (target = watch_parent_process , args = (processId ,))
211+             self .watching_thread .daemon  =  True 
212+             self .watching_thread .start ()
203213        # Get our capabilities 
204214        return  {'capabilities' : self .capabilities ()}
205215
0 commit comments