;; -*- Mode: Irken -*- ;; will need two CVs eventually. the obvious one for read, ;; but if/when we honor window sizes, we will need a CV for write. (define (make-channel c2s-id s2c-id winsz maxpkt session-handler channel-write) (let ((read-cv (cv/make)) (write-cv (cv/make)) (rqueue (queue/make)) (wqueue (queue/make))) (define (recv data) (queue/add! rqueue data) (read-cv.wake-one) ) (define (read) (when (= rqueue.len 0) (read-cv.wait)) (let ((pieces (list:nil))) (while (> rqueue.len 0) (when-maybe piece (queue/pop! rqueue) (push! pieces piece))) (string-concat (reverse pieces)) )) ;; (define (write data) ;; (queue/add! wqueue data) ;; (write-cv.wake_one)) (define (write data) (channel-write c2s-id data)) (poller/fork (lambda () (session-handler read write))) { c2s-id = c2s-id s2c-id = s2c-id winsz = winsz maxpkt = maxpkt recv = recv } )) (define (make-channel-manager) (let ((map (tree/empty)) (counter 0)) (define (next-id) (let ((r counter)) (inc! counter) r)) (define (new c2s-chan winsz maxpkt session-handler write) (let ((chan-id (next-id)) (chan (make-channel c2s-chan chan-id winsz maxpkt session-handler write))) (tree/insert! map int-cmp chan-id chan) chan )) (define (close c2s-id s2c-id) (tree/delete! map int-cmp s2c-id)) (define (lookup s2c-id) (tree/member map int-cmp s2c-id)) { new = new lookup = lookup close = close } ))