placeholder.scm 1.7 KB

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