impl-abcl.lisp - clic - Clic is an command line interactive client for gopher written in Common LISP (HTM) git clone git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/ (DIR) Log (DIR) Files (DIR) Refs (DIR) Tags (DIR) README (DIR) LICENSE --- impl-abcl.lisp (4319B) --- 1 ;;;; -*- indent-tabs-mode: nil -*- 2 3 #| 4 Copyright 2006, 2007 Greg Pfeil 5 6 Reimplemented with java.util.concurrent.locks.ReentrantLock by Mark Evenson 2011. 7 8 Distributed under the MIT license (see LICENSE file) 9 |# 10 11 (in-package #:bordeaux-threads) 12 13 ;;; the implementation of the Armed Bear thread interface can be found in 14 ;;; src/org/armedbear/lisp/LispThread.java 15 16 (deftype thread () 17 'threads:thread) 18 19 ;;; Thread Creation 20 21 (defun %make-thread (function name) 22 (threads:make-thread function :name name)) 23 24 (defun current-thread () 25 (threads:current-thread)) 26 27 (defun thread-name (thread) 28 (threads:thread-name thread)) 29 30 (defun threadp (object) 31 (typep object 'thread)) 32 33 ;;; Resource contention: locks and recursive locks 34 35 (defstruct mutex name lock) 36 (defstruct (mutex-recursive (:include mutex))) 37 38 ;; Making methods constants in this manner avoids the runtime expense of 39 ;; introspection involved in JCALL with string arguments. 40 (defconstant +lock+ 41 (jmethod "java.util.concurrent.locks.ReentrantLock" "lock")) 42 (defconstant +try-lock+ 43 (jmethod "java.util.concurrent.locks.ReentrantLock" "tryLock")) 44 (defconstant +is-held-by-current-thread+ 45 (jmethod "java.util.concurrent.locks.ReentrantLock" "isHeldByCurrentThread")) 46 (defconstant +unlock+ 47 (jmethod "java.util.concurrent.locks.ReentrantLock" "unlock")) 48 (defconstant +get-hold-count+ 49 (jmethod "java.util.concurrent.locks.ReentrantLock" "getHoldCount")) 50 51 (deftype lock () 'mutex) 52 53 (deftype recursive-lock () 'mutex-recursive) 54 55 (defun lock-p (object) 56 (typep object 'mutex)) 57 58 (defun recursive-lock-p (object) 59 (typep object 'mutex-recursive)) 60 61 (defun make-lock (&optional name) 62 (make-mutex 63 :name (or name "Anonymous lock") 64 :lock (jnew "java.util.concurrent.locks.ReentrantLock"))) 65 66 (defun acquire-lock (lock &optional (wait-p t)) 67 (check-type lock mutex) 68 (when (jcall +is-held-by-current-thread+ (mutex-lock lock)) 69 (error "Non-recursive lock being reacquired by owner.")) 70 (cond 71 (wait-p 72 (jcall +lock+ (mutex-lock lock)) 73 t) 74 (t (jcall +try-lock+ (mutex-lock lock))))) 75 76 (defun release-lock (lock) 77 (check-type lock mutex) 78 (unless (jcall +is-held-by-current-thread+ (mutex-lock lock)) 79 (error "Attempt to release lock not held by calling thread.")) 80 (jcall +unlock+ (mutex-lock lock)) 81 (values)) 82 83 (defun make-recursive-lock (&optional name) 84 (make-mutex-recursive 85 :name (or name "Anonymous lock") 86 :lock (jnew "java.util.concurrent.locks.ReentrantLock"))) 87 88 (defun acquire-recursive-lock (lock &optional (wait-p t)) 89 (check-type lock mutex-recursive) 90 (cond 91 (wait-p 92 (jcall +lock+ (mutex-recursive-lock lock)) 93 t) 94 (t (jcall +try-lock+ (mutex-recursive-lock lock))))) 95 96 (defun release-recursive-lock (lock) 97 (check-type lock mutex-recursive) 98 (unless (jcall +is-held-by-current-thread+ (mutex-lock lock)) 99 (error "Attempt to release lock not held by calling thread.")) 100 (jcall +unlock+ (mutex-lock lock)) 101 (values)) 102 103 ;;; Resource contention: condition variables 104 105 (defun thread-yield () 106 (java:jstatic "yield" "java.lang.Thread")) 107 108 (defstruct condition-variable 109 (name "Anonymous condition variable")) 110 111 (defun condition-wait (condition lock &key timeout) 112 (threads:synchronized-on condition 113 (release-lock lock) 114 (if timeout 115 ;; Since giving a zero time value to threads:object-wait means 116 ;; an indefinite wait, use some arbitrary small number. 117 (threads:object-wait condition 118 (if (zerop timeout) 119 least-positive-single-float 120 timeout)) 121 (threads:object-wait condition))) 122 (acquire-lock lock) 123 t) 124 125 (defun condition-notify (condition) 126 (threads:synchronized-on condition 127 (threads:object-notify condition))) 128 129 ;;; Introspection/debugging 130 131 (defun all-threads () 132 (let ((threads ())) 133 (threads:mapcar-threads (lambda (thread) 134 (push thread threads))) 135 (reverse threads))) 136 137 (defun interrupt-thread (thread function &rest args) 138 (apply #'threads:interrupt-thread thread function args)) 139 140 (defun destroy-thread (thread) 141 (signal-error-if-current-thread thread) 142 (threads:destroy-thread thread)) 143 144 (defun thread-alive-p (thread) 145 (threads:thread-alive-p thread)) 146 147 (defun join-thread (thread) 148 (threads:thread-join thread)) 149 150 (mark-supported)