nodes: 0, module; 1, function_definition; 2, function_name:__cleanup; 3, parameters; 4, block; 5, identifier:self; 6, expression_statement; 7, comment:# set run to False and wait some time -> see what happens; 8, expression_statement; 9, if_statement; 10, try_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, comment:"""
          Wait at most twice as long as the given repetition interval
          for the _wrapper_function to terminate.
          
          If after that time the _wrapper_function has not terminated,
          send SIGTERM to and the process.
          
          Wait at most five times as long as the given repetition interval
          for the _wrapper_function to terminate.
          
          If the process still running send SIGKILL automatically if
          auto_kill_on_last_resort was set True or ask the
          user to confirm sending SIGKILL
          """; 16, assignment; 17, call; 18, block; 19, else_clause; 20, block; 21, except_clause; 22, call; 23, call; 24, call; 25, assignment; 26, attribute; 27, False; 28, identifier:check_process_termination; 29, argument_list; 30, expression_statement; 31, block; 32, expression_statement; 33, expression_statement; 34, identifier:OSError; 35, block; 36, attribute; 37, argument_list; 38, attribute; 39, argument_list; 40, attribute; 41, argument_list; 42, attribute; 43, False; 44, attribute; 45, identifier:value; 46, keyword_argument; 47, keyword_argument; 48, keyword_argument; 49, keyword_argument; 50, call; 51, raise_statement; 52, call; 53, call; 54, pass_statement; 55, identifier:log; 56, identifier:debug; 57, string:"wait for monitor thread to join"; 58, attribute; 59, identifier:join; 60, identifier:log; 61, identifier:debug; 62, string:"monitor thread to joined"; 63, attribute; 64, identifier:value; 65, identifier:self; 66, identifier:_run; 67, identifier:proc; 68, attribute; 69, identifier:timeout; 70, binary_operator:2*self.interval; 71, identifier:prefix; 72, string; 73, identifier:auto_kill_on_last_resort; 74, attribute; 75, attribute; 76, argument_list; 77, call; 78, attribute; 79, argument_list; 80, attribute; 81, argument_list; 82, identifier:self; 83, identifier:_monitor_thread; 84, identifier:self; 85, identifier:_func_running; 86, identifier:self; 87, identifier:_proc; 88, integer:2; 89, attribute; 90, identifier:self; 91, identifier:_auto_kill_on_last_resort; 92, identifier:log; 93, identifier:debug; 94, string:"cleanup successful"; 95, identifier:RuntimeError; 96, argument_list; 97, attribute; 98, identifier:close; 99, attribute; 100, identifier:stop; 101, identifier:self; 102, identifier:interval; 103, string:"cleanup FAILED!"; 104, identifier:self; 105, identifier:conn_send; 106, identifier:self; 107, identifier:_log_queue_listener
code: def __cleanup(self):
          """
          Wait at most twice as long as the given repetition interval
          for the _wrapper_function to terminate.
          
          If after that time the _wrapper_function has not terminated,
          send SIGTERM to and the process.
          
          Wait at most five times as long as the given repetition interval
          for the _wrapper_function to terminate.
          
          If the process still running send SIGKILL automatically if
          auto_kill_on_last_resort was set True or ask the
          user to confirm sending SIGKILL
          """
          # set run to False and wait some time -> see what happens            
          self._run.value = False
          if check_process_termination(proc                     = self._proc,
                                       timeout                  = 2*self.interval,
                                       prefix                   = '',
                                       auto_kill_on_last_resort = self._auto_kill_on_last_resort):
              log.debug("cleanup successful")
          else:
              raise RuntimeError("cleanup FAILED!")
          try:
              self.conn_send.close()
              self._log_queue_listener.stop()
          except OSError:
              pass
          log.debug("wait for monitor thread to join")
          self._monitor_thread.join()
          log.debug("monitor thread to joined")
          self._func_running.value = False