Method: OpenC3.kill_thread

Defined in:
lib/openc3/top_level.rb

.kill_thread(owner, thread, graceful_timeout = 1, timeout_interval = 0.01, hard_timeout = 1) ⇒ Object

Attempt to gracefully kill a thread

Parameters:

  • owner

    Object that owns the thread and may have a graceful_kill method

  • thread

    The thread to gracefully kill

  • graceful_timeout (defaults to: 1)

    Timeout in seconds to wait for it to die gracefully

  • timeout_interval (defaults to: 0.01)

    How often to poll for aliveness

  • hard_timeout (defaults to: 1)

    Timeout in seconds to wait for it to die ungracefully



498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'lib/openc3/top_level.rb', line 498

def self.kill_thread(owner, thread, graceful_timeout = 1, timeout_interval = 0.01, hard_timeout = 1)
  if thread
    if owner and owner.respond_to? :graceful_kill
      if Thread.current != thread
        owner.graceful_kill
        end_time = Time.now.sys + graceful_timeout
        while thread.alive? && ((end_time - Time.now.sys) > 0)
          sleep(timeout_interval)
        end
      else
        Logger.warn "Threads cannot graceful_kill themselves"
      end
    elsif owner
      Logger.info "Thread owner #{owner.class} does not support graceful_kill"
    end
    if thread.alive?
      # If the thread dies after alive? but before backtrace, bt will be nil.
      bt = thread.backtrace

      # Graceful failed
      msg =  "Failed to gracefully kill thread:\n"
      msg << "  Caller Backtrace:\n  #{caller().join("\n  ")}\n"
      msg << "  \n  Thread Backtrace:\n  #{bt.join("\n  ")}\n" if bt
      msg << "\n"
      Logger.warn msg
      thread.kill
      end_time = Time.now.sys + hard_timeout
      while thread.alive? && ((end_time - Time.now.sys) > 0)
        sleep(timeout_interval)
      end
    end
    if thread.alive?
      Logger.error "Failed to kill thread"
    end
  end
end