(define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((protected (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) (protected withdraw)) ((eq? m 'deposit) (protected deposit)) ((eq? m 'balance) ((protected (lambda () balance)))) ; serialized (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch)) ; Whether or not reading the balance needs serialization depends on whether ; set! and reading a variable are atomic. If set! or read is not atomic, then ; an unprotected read may read at the same time as a deposit or withdrawal may ; read a mixture of the previous and new balances which is invalid (ex: high ; order bits may be from previous, while low order bits may be from new). ; ; If reading a name's value and set! are atomic, then no additional ; serialization is needed. Reading does not interfere with deposit or withdraw ; because it does not modify the balance.