def close
    sd_thread = nil

    @mutex.synchronize do
      return unless @czk
      inst, @czk = @czk, nil
    
      sd_thread = Thread.new(inst) do |_inst|
        stop_dispatch_thread!
        _inst.close
      end
    end

    # if we're on the event dispatch thread for some stupid reason, then don't join
    unless event_dispatch_thread?
      # hard-coded 30 second delay, don't hang forever
      if sd_thread.join(30) != sd_thread 
        logger.error { "timed out waiting for shutdown thread to exit" }
      end
    end

    nil
  end
def close
    sd_thread = nil

    @mutex.synchronize do
      return unless @czk
      inst, @czk = @czk, nil
    
      sd_thread = Thread.new(inst) do |_inst|
        stop_dispatch_thread!
        _inst.close
      end
    end

    # if we're on the event dispatch thread for some stupid reason, then don't join
    unless event_dispatch_thread?
      # hard-coded 30 second delay, don't hang forever
      if sd_thread.join(30) != sd_thread 
        logger.error { "timed out waiting for shutdown thread to exit" }
      end
    end

    nil
  end
close the connection normally, stops the dispatch thread and closes the
 underlying connection cleanly