61 lines
1.8 KiB
Racket
61 lines
1.8 KiB
Racket
#lang racket/base
|
|
;; Issue requests in order, process them in any order (or in
|
|
;; parallel), reassemble the ordering at the end.
|
|
|
|
;; What I'm doing here reminded me of the signal-notification
|
|
;; mechanism from [1], but is actually quite different.
|
|
;;
|
|
;; [1] O. Shivers, "Automatic management of operating-system
|
|
;; resources," in Proceedings of the Second ACM SIGPLAN International
|
|
;; Conference on Functional Programming (ICFP '97), 1997, vol. 32,
|
|
;; no. 8, pp. 274-279.
|
|
|
|
(require "functional-queue.rkt")
|
|
|
|
(provide make-transaction-manager
|
|
|
|
transaction-manager?
|
|
open-transaction
|
|
close-transaction!
|
|
transaction-available?
|
|
dequeue-transaction
|
|
|
|
transaction?
|
|
transaction-context
|
|
transaction-value)
|
|
|
|
(struct transaction-manager (queue) #:transparent)
|
|
|
|
(struct transaction (context
|
|
[value* #:mutable]
|
|
[ready? #:mutable]))
|
|
|
|
(define (make-transaction-manager)
|
|
(transaction-manager (make-queue)))
|
|
|
|
(define (open-transaction manager context)
|
|
(define txn (transaction context #f #f))
|
|
(values txn (transaction-manager (enqueue (transaction-manager-queue manager) txn))))
|
|
|
|
(define (close-transaction! txn value)
|
|
(when (transaction-ready? txn)
|
|
(error 'close-transaction! "Attempt to close previously-closed transaction"))
|
|
(set-transaction-value*! txn value)
|
|
(set-transaction-ready?! txn #t)
|
|
value)
|
|
|
|
(define (transaction-available? manager)
|
|
(if (queue-empty? (transaction-manager-queue manager))
|
|
#f
|
|
(let-values (((txn rest) (dequeue (transaction-manager-queue manager))))
|
|
(transaction-ready? txn))))
|
|
|
|
(define (dequeue-transaction manager)
|
|
(let-values (((txn rest) (dequeue (transaction-manager-queue manager))))
|
|
(values txn (transaction-manager rest))))
|
|
|
|
(define (transaction-value txn)
|
|
(when (not (transaction-ready? txn))
|
|
(error 'transaction-value "Attempt to extract value from unclosed transaction"))
|
|
(transaction-value* txn))
|