      (deref (p/finally d (fn [_ _] (p/cancel! t)))))))
 
 (defn <!
-  "Perform a blocking take operation on the channel."
+  "Perform a blocking put operation with optional timeout
+  handling. Analogous to @(take! port)."
   ([port]
    (-> (take! port)
        (deref)))

    ret))

(defn close!
  [port]
  (pt/-close! port)
  nil)

(defn closed?
  [port]
  (pt/-closed? port))

(defn timeout
  [ms]
  (let [ch (chan)]
    (px/schedule! ms #(pt/-close! ch))
    ch))

(defn slidding-buffer
  [n]
  (buffers/slidding n))

(defn dropping-buffer
  [n]
  (buffers/dropping n))

(defn fixed-buffer
  [n]
  (buffers/fixed n))

(defn offer!
  [port val]
  (let [o (volatile! nil)]
    (pt/-put! port val (channel/volatile->handler o))
    @o))

(defn poll!
  [port]
  (let [o (volatile! nil)]
    (pt/-take! port (channel/volatile->handler o))
    @o))

(defn pipe
  ([from to] (pipe from to true))
  ([from to close?]
   (go-loop []
     (let [v (<! from)]
       (if (nil? v)
         (when close? (close! to))
         (when (>! to v)
           (recur)))))
   to))

(defn onto-chan!
  ([ch coll] (onto-chan! ch coll true))
  ([ch coll close?]
   (go-loop [items (seq coll)]
     (if (and items (>! ch (first items)))
       (recur (next items))
       (when close?
         (close! ch))))))

     (channel/chan buf xf exh))))

(defn put!
  "Schedules a put operation on the channel. Returns a promise
  instance that will resolve to: false if channel is closed, true if
  put is succeed. If channel has buffer, it will return immediatelly
  with resolved promise."
  [port val]
  (let [d (p/deferred)]
    (pt/-put! port val (channel/promise->handler d))
    d))

(defn take!
  "Schedules a take operation on the channel. Returns a promise
  instance that will resolve to: nil if channel is closed, obj if
  value is found. If channel has non-empty buffer the take operation
  will succeed immediatelly with resolved promise."
  [port]
  (let [d (p/deferred)]
    (pt/-take! port (channel/promise->handler d))
    d))

(defn >!
  "Perform a blocking put operation with optional timeout
  handling. Analogous to @(put! port val)."
  ([port val]
   (-> (put! port val)
       (deref)))
