proposal.scm 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Higher-level proposal stuff.
  3. ; Execute THUNK atomically with its own proposal, saving and restoring
  4. ; the current proposal.
  5. (define (call-atomically thunk)
  6. (let ((old (current-proposal)))
  7. (let loop ()
  8. (set-current-proposal! (make-proposal))
  9. (call-with-values thunk
  10. (lambda results
  11. (if (maybe-commit)
  12. (begin
  13. (set-current-proposal! old)
  14. (apply values results))
  15. (loop)))))))
  16. ; Ditto, but no values are returned.
  17. (define (call-atomically! thunk)
  18. (with-new-proposal (lose)
  19. (thunk)
  20. (or (maybe-commit)
  21. (lose)))
  22. (values))
  23. ; Same again, except that we use the current proposal, if there is one
  24. ; (and don't commit on the existing proposal).
  25. (define (call-ensuring-atomicity thunk)
  26. (if (current-proposal)
  27. (thunk)
  28. (call-atomically thunk)))
  29. (define (call-ensuring-atomicity! thunk)
  30. (if (current-proposal)
  31. (thunk)
  32. (call-atomically! thunk)))
  33. ; Macro versions of the above that avoid the need to write (lambda () ...)
  34. ; around the critical section.
  35. (define-syntax atomically
  36. (syntax-rules ()
  37. ((atomically)
  38. (unspecific))
  39. ((atomically body ...)
  40. (call-atomically
  41. (lambda () body ...)))))
  42. (define-syntax atomically!
  43. (syntax-rules ()
  44. ((atomically)
  45. (values))
  46. ((atomically body ...)
  47. (call-atomically!
  48. (lambda () body ...)))))
  49. (define-syntax ensure-atomicity
  50. (syntax-rules ()
  51. ((ensure-atomicity)
  52. (unspecific))
  53. ((ensure-atomicity body ...)
  54. (call-ensuring-atomicity
  55. (lambda () body ...)))))
  56. (define-syntax ensure-atomicity!
  57. (syntax-rules ()
  58. ((ensure-atomicity)
  59. (values))
  60. ((ensure-atomicity body ...)
  61. (call-ensuring-atomicity!
  62. (lambda () body ...)))))
  63. ; Save the existing proposal, install a new one, execute the body, and then
  64. ; replace the original proposal.
  65. (define-syntax with-new-proposal
  66. (syntax-rules ()
  67. ((with-new-proposal (?lose) ?body ?more ...)
  68. (let ((old (current-proposal)))
  69. (call-with-values
  70. (lambda ()
  71. (let ?lose ()
  72. (set-current-proposal! (make-proposal))
  73. (begin ?body ?more ...)))
  74. (lambda results
  75. (set-current-proposal! old)
  76. (apply values results)))))))
  77. ; Useful for getting rid of a proposal before raising an error.
  78. (define (remove-current-proposal!)
  79. (set-current-proposal! #f))
  80. ; For use when an inconsistency has been detected. The SET-CAR! ensures that
  81. ; the earlier PROVISIONAL-CAR will fail.
  82. (define (invalidate-current-proposal!)
  83. (let ((value (provisional-car j-random-pair)))
  84. (set-car! j-random-pair (cons #f #f))
  85. value))
  86. (define j-random-pair (list #f))