;;; Functional event system.
;;; System by Olin Shivers, implementation by David Fisher

(define-record event
  type
  (next (make-placeholder))
  ((disclose e) (list "event" (event:type e))))

;Not exported!
(define *most-recent-event* (make-event interrupt/cont))

(define event-lock (make-lock))

(define (most-recent-event) *most-recent-event*)

(define (next-event event) (placeholder-value (event:next event)))

(define (event-type event) (event:type event))

;Called when the interrupt actually happened.
(define (register-interrupt type)
  (obtain-lock event-lock)
  (let ((new-event (make-event type)))
    (placeholder-set! (event:next *most-recent-event*) new-event)
    (set! *most-recent-event* new-event))
  (release-lock event-lock))

;Wait for an event of a certain type.
(define (wait-interrupt type pre-event)
  (let ((event (next-event pre-event)))
    (if (eq? (event-type event) type)
	event
	(wait-interrupt type event))))

;Initialize the system.
(define (install-event-handlers!)
  (let loop ((count 0))
    (if (< count interrupt-count)
	(let ((old-handler (vector-ref (interrupt-handlers-vector) count)))
	  (set-interrupt-handler
	   count
	   (lambda stuff
	     (register-interrupt count)
	     (apply old-handler stuff)))
	  (loop (+ count 1))))))