conditions.scm 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. ;;; Hoot implementation of Fibers
  2. ;;; Copyright (C) 2024 Igalia, S.L.
  3. ;;;
  4. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  5. ;;; you may not use this file except in compliance with the License.
  6. ;;; You may obtain a copy of the License at
  7. ;;;
  8. ;;; http://www.apache.org/licenses/LICENSE-2.0
  9. ;;;
  10. ;;; Unless required by applicable law or agreed to in writing, software
  11. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  12. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. ;;; See the License for the specific language governing permissions and
  14. ;;; limitations under the License.
  15. (define-module (fibers conditions)
  16. #:use-module (srfi srfi-9)
  17. #:use-module (ice-9 match)
  18. #:use-module (fibers waiter-queue)
  19. #:use-module (fibers operations)
  20. #:export (make-condition
  21. condition?
  22. signal-condition!
  23. wait-operation
  24. wait))
  25. (define-record-type <condition>
  26. (%make-condition signalled? waiters)
  27. condition?
  28. (signalled? condition-signalled? set-condition-signalled?!)
  29. (waiters condition-waiters))
  30. (define (make-condition)
  31. "Make a fresh condition variable."
  32. (%make-condition #f (make-waiter-queue)))
  33. (define (signal-condition! cvar)
  34. "Mark @var{cvar} as having been signalled. Resume any fiber or
  35. thread waiting for @var{cvar}. If @var{cvar} is already signalled,
  36. calling @code{signal-condition!} does nothing and returns @code{#f};
  37. returns @code{#t} otherwise."
  38. (match cvar
  39. (($ <condition> #f waiters)
  40. (set-condition-signalled?! cvar #t)
  41. (waiter-queue-pop-all! waiters (lambda (resume) (resume values)))
  42. #t)
  43. (($ <condition>)
  44. #f)))
  45. (define (wait-operation cvar)
  46. "Make an operation that will complete when @var{cvar} is signalled."
  47. (match cvar
  48. (($ <condition> _ waiters)
  49. (define (try-fn)
  50. (and (condition-signalled? cvar) (lambda () (values))))
  51. (define (block-fn state resume)
  52. (waiter-queue-push! waiters state resume)
  53. (values))
  54. (make-base-operation #f try-fn block-fn))))
  55. (define (wait cvar)
  56. "Wait until @var{cvar} has been signalled."
  57. (perform-operation (wait-operation cvar)))