#lang scheme/base

(define (make-pool-for-each n)
  (λ (proc items)
    (define tasks (make-channel))
    (define results (make-semaphore))
    (define threads #f)
    (dynamic-wind
     (λ ()
       (set! threads
             (build-list
              n
              (λ (i)
                (thread
                 (λ ()
                   (let loop ()
                     (let ((value (channel-get tasks)))
                       (proc value))
                     (semaphore-post results)
                     (loop))))))))
     (λ ()
       (for-each 
        (λ (item)
          (channel-put tasks item))
        items)
       (for-each
        (λ (item)
          (semaphore-wait results))
        items))
     (λ ()
       (for-each
        (λ (thread)
          (kill-thread thread)
          (thread-wait thread))
        threads)))))

(define (example)
  (define pool-for-each (make-pool-for-each 20))
  
  (pool-for-each
   (λ (i)
;     (display (format "~s~n" (* C (exp (* r i)))))
     (sleep 1)
     (display i)(display "-")
     (flush-output))
   ; note reverse order!
   (build-list 100 (λ (i) (- 100 i)))))

(provide make-pool-for-each)