 
 (declare bind-to-show)
 
+(defonce ^:private ^{:doc "The thread used to run [[bind-bottleneck]]
+  and serialize the auto-binding of potential controllers that have
+  been found."}
+  auto-bind-thread
+  (atom nil))
+
 (defn- bind-bottleneck
   "Takes potential auto-bind devices from the incoming queue one by
   one and tries binding to them. This is used to make sure that we are
   only trying one device at a time, taking as long as it needs,
-  without backing up the main MIDI event handler thread."
+  without backing up the main MIDI event handler thread.
+
+  Entries on the cue are a tuple containing the device which has been
+  identified as a potential new controller port, the show to which it
+  should be bound if it turns out to be suitable, and any optional
+  arguments which should be passed along to [[bind-to-show]].
+
+  If the special flag value `:done` is passed as the third element in
+  the tuple, it signals the loop to end, because auto-binding has been
+  canceled."
   []
   (loop [[device show args] (.take bind-queue)]
     (when device

                                                    {:auto-binding   true
                                                     :new-connection new-connection})]))))]

    ;; See if our controller seems to already be connected, and if so, try bind to it right away.
    (doseq [found (amidi/filter-devices device-filter (amidi/open-inputs-if-needed!))]
      (when-not (already-bound? found) (connection-handler found false)))


(defn cancel-auto-bind
  "Stop any [[auto-bind]] which may be in effect."
  []
  (swap! auto-bind-handler (fn [former-handler]  ; Stop noticing new device connections
                             (when former-handler
                               (amidi/remove-new-device-handler! former-handler))
                             nil))
  (.add bind-queue [nil nil :done]))  ; Tell the auto-bind thread to shut down
