home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode: LISP; Syntax: Common-lisp; Package: PROCESS; Base: 10; Lowercase: Yes -*-
-
- (defflavor xlib::clx-lock () (simple-recursive-normal-lock)
- (:init-keywords :flavor))
-
- (defwhopper (lock-internal xlib::clx-lock) (lock-argument)
- (catch 'timeout
- (continue-whopper lock-argument)))
-
- (defmethod (lock-block-internal xlib::clx-lock) (lock-argument)
- (declare (dbg:locking-function describe-process-lock-for-debugger self))
- (when (null waiter-queue)
- (setf waiter-queue (make-scheduler-queue :name name))
- (setf timer (create-timer-call #'lock-timer-expired `(,self) :name name)))
- (let ((process (lock-argument-process lock-argument)))
- (unwind-protect
- (progn
- (lock-map-over-conflicting-owners
- self lock-argument
- #'(lambda (other-lock-arg)
- (add-promotion process lock-argument
- (lock-argument-process other-lock-arg) other-lock-arg)))
- (unless (timer-pending-p timer)
- (when (and (safe-to-use-timers %real-current-process)
- (not dbg:*debugger-might-have-system-problems*))
- (reset-timer-relative-timer-units timer *lock-timer-interval*)))
- (assert (store-conditional (locf latch) process nil))
- (sys:with-aborts-enabled (lock-latch)
- (let ((timeout (lock-argument-getf lock-argument :timeout nil)))
- (cond ((null timeout)
- (promotion-block waiter-queue name #'lock-lockable self lock-argument))
- ((and (plusp timeout)
- (using-resource (timer process-block-timers)
- ;; Yeah, we know about the internal representation
- ;; of timers here.
- (setf (car (timer-args timer)) %real-current-process)
- (with-scheduler-locked
- (reset-timer-relative timer timeout)
- (flet ((lock-lockable-or-timeout (timer lock lock-argument)
- (or (not (timer-pending-p timer))
- (lock-lockable lock lock-argument))))
- (let ((priority (process-process-priority *current-process*)))
- (if (ldb-test %%scheduler-priority-preemption-field priority)
- (promotion-block waiter-queue name
- #'lock-lockable-or-timeout
- timer self lock-argument)
- ;; Change to preemptive priority so that when
- ;; unlock-internal wakes us up so we can have the lock,
- ;; we will really wake up right away
- (with-process-priority
- (dpb 1 %%scheduler-priority-preemption-field
- priority)
- (promotion-block waiter-queue name
- #'lock-lockable-or-timeout
- timer self lock-argument)))))
- (lock-lockable self lock-argument)))))
- (t (throw 'timeout nil))))))
- (unless (store-conditional (locf latch) nil process)
- (lock-latch-wait-internal self))
- (remove-promotions process lock-argument))))
-
- (compile-flavor-methods xlib::clx-lock)
-