placeholder.scm 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Placeholders (single-assignment cells for use with threads)
  3. (define-synchronized-record-type placeholder :placeholder
  4. (really-make-placeholder value queue id)
  5. (value queue) ; synchronize on this
  6. placeholder?
  7. (queue placeholder-queue set-placeholder-queue!) ; #f means VALUE has been set
  8. (value placeholder-real-value set-placeholder-value!)
  9. (id placeholder-id))
  10. (define-record-discloser :placeholder
  11. (lambda (placeholder)
  12. (cons 'placeholder
  13. (if (placeholder-id placeholder)
  14. (list (placeholder-id placeholder))
  15. '()))))
  16. (define (make-placeholder . id-option)
  17. (really-make-placeholder (unspecific)
  18. (make-queue)
  19. (if (null? id-option) #f (car id-option))))
  20. (define (placeholder-value placeholder)
  21. (with-new-proposal (lose)
  22. (let ((queue (placeholder-queue placeholder)))
  23. (if queue
  24. (or (maybe-commit-and-block-on-queue queue)
  25. (lose)))))
  26. (placeholder-real-value placeholder))
  27. (define (placeholder-set! placeholder new-value)
  28. (with-new-proposal (lose)
  29. (let ((queue (placeholder-queue placeholder)))
  30. (cond (queue
  31. (set-placeholder-value! placeholder new-value)
  32. (set-placeholder-queue! placeholder #f)
  33. (or (maybe-commit-and-make-ready queue)
  34. (lose)))
  35. (else
  36. ;; We only read queue and value and they are set atomically,
  37. ;; so there is no need to commit here.
  38. (error "placeholder is already assigned"
  39. placeholder
  40. (placeholder-real-value placeholder)))))))