;; Don't need active-writer; if a writer has the lock then its active. ;; If writers-waiting > 0 then readers should defer. (defmacro write-with-rw-lock ((reader-writer-lock) &body body) (let ((retval (gensym)) (lock (gensym))) `(let ((,retval nil) (,lock ,reader-writer-lock)) (with-accessors ((g g-lock) (ra readers-active) (ww writers-waiting) (c-var condition-var)) ,lock (bt:with-lock-held (g) (unwind-protect (incf ww) (unwind-protect (progn (while-loop (> ra 0) (bt:condition-wait c-var g)) (setf ,retval (multiple-value-list (progn ,@body)))) (decf ww) (bt:condition-notify c-var))))) (values-list ,retval))))