commit c87dae16f8fb32057362822d7cc15cac903f125c
parent de3cd60876ad2961e3063450b791d2b505a100b0
Author: Tomas Hlavaty <tom@logand.com>
Date: Sun, 13 Mar 2016 18:01:41 +0100
less macros more thunks
Diffstat:
M | concurrency.lisp | | | 94 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | dns.lisp | | | 29 | ++++++++++++++++------------- |
M | os.lisp | | | 13 | ++++++------- |
M | socket.lisp | | | 11 | ++++------- |
M | ui.lisp | | | 58 | +++++++++++++++++++++++++++++++--------------------------- |
5 files changed, 106 insertions(+), 99 deletions(-)
diff --git a/concurrency.lisp b/concurrency.lisp
@@ -22,27 +22,27 @@
(defpackage :rw.concurrency
(:use :cl)
- (:export :with-lock
+ (:export :make-concurrent-queue
:make-lock
+ :make-program-server
:make-semaphore
- :signal-semaphore
- :wait-on-semaphore
- :make-concurrent-queue
:make-thread
- :make-program-server
- :threads-supported-p))
+ :signal-semaphore
+ :threads-supported-p
+ :using-lock
+ :wait-on-semaphore))
(in-package :rw.concurrency)
-(defmacro with-lock ((lock) &body body)
+(defun using-lock (lock thunk)
#-(or allegro ccl ecl mkcl cmucl sbcl)
- (error "RW.CONCURRENCY:WITH-LOCK not ported")
- #+allegro `(mp:with-process-lock (,lock) ,@body)
- #+ccl `(ccl:with-lock-grabbed (,lock) ,@body)
- #+ecl `(mp:with-lock (,lock) ,@body)
- #+mkcl `(mt:with-lock (,lock) ,@body)
- #+cmucl `(mp:with-lock-held (,lock) ,@body)
- #+sbcl `(sb-concurrency::with-mutex (,lock) ,@body))
+ (error "RW.CONCURRENCY:USING-LOCK not ported")
+ #+allegro (mp:with-process-lock (lock) (funcall thunk))
+ #+ccl (ccl:with-lock-grabbed (lock) (funcall thunk))
+ #+ecl (mp:with-lock (lock) (funcall thunk))
+ #+mkcl (mt:with-lock (lock) (funcall thunk))
+ #+cmucl (mp:with-lock-held (lock) (funcall thunk))
+ #+sbcl (sb-concurrency::with-mutex (lock) (funcall thunk)))
(defun make-lock (name)
#-(or allegro ccl ecl mkcl cmucl sbcl)
@@ -88,20 +88,22 @@
(lambda (&optional (value nil valuep))
(if valuep
(let ((y (cons value nil)))
- (with-lock (l)
- (setf (cdar x) y
- (car x) y)
- (signal-semaphore s))
+ (using-lock l
+ (lambda ()
+ (setf (cdar x) y
+ (car x) y)
+ (signal-semaphore s)))
value)
(do (done z)
(done z)
(wait-on-semaphore s)
- (with-lock (l)
- (unless (eq x (car x))
- (setq done t
- z (pop (cdr x)))
- (unless (cdr x)
- (setf (car x) x)))))))))
+ (using-lock l
+ (lambda ()
+ (unless (eq x (car x))
+ (setq done t
+ z (pop (cdr x)))
+ (unless (cdr x)
+ (setf (car x) x))))))))))
;; (setq q (make-concurrent-queue))
;; (funcall q 1)
@@ -113,16 +115,16 @@
#+(or allegro ccl ecl mkcl cmucl sb-thread (and clisp mt))
t)
-(defun make-thread (name fn)
+(defun make-thread (name thunk)
#-(or allegro ccl ecl mkcl cmucl sbcl (and clisp mt))
(error "RW.CONCURRENCY:MAKE-THREAD not ported")
- #+allegro (mp:process-run-function name fn)
- #+ccl (ccl:process-run-function name fn)
- #+ecl (mp:process-run-function name fn)
- #+mkcl (mt:thread-run-function name fn)
- #+cmucl (mp:make-process fn :name name)
- #+sbcl (sb-concurrency::make-thread fn :name (string name))
- #+(and clisp mt) (mt:make-thread fn :name name))
+ #+allegro (mp:process-run-function name thunk)
+ #+ccl (ccl:process-run-function name thunk)
+ #+ecl (mp:process-run-function name thunk)
+ #+mkcl (mt:thread-run-function name thunk)
+ #+cmucl (mp:make-process thunk :name name)
+ #+sbcl (sb-concurrency::make-thread thunk :name (string name))
+ #+(and clisp mt) (mt:make-thread thunk :name name))
(defun make-program-server (command args writer reader)
(let ((p (rw.os:make-program :stream :stream command args nil))
@@ -137,16 +139,18 @@
(let ((l (make-lock 'program-server-lock))
(s (funcall p :output-stream)))
(lambda (query)
- (with-lock (l)
- (when wq
- (cond
- (query
- (funcall wq query)
- (funcall reader s))
- (t
- (funcall wq nil)
- (setq wq nil)
- (funcall p :wait)
- (multiple-value-bind (status code) (funcall p :status-and-code)
- (assert (eq :exited status))
- (assert (zerop code)))))))))))
+ (using-lock l
+ (lambda ()
+ (when wq
+ (cond
+ (query
+ (funcall wq query)
+ (funcall reader s))
+ (t
+ (funcall wq nil)
+ (setq wq nil)
+ (funcall p :wait)
+ (multiple-value-bind (status code)
+ (funcall p :status-and-code)
+ (assert (eq :exited status))
+ (assert (zerop code))))))))))))
diff --git a/dns.lisp b/dns.lisp
@@ -282,19 +282,22 @@
($resource additional :size nadditional))
(defun udp (buf server port)
- (rw.socket:with-socket (s (rw.socket:make-udp-socket))
- (rw.socket:udp-send s buf (length buf)
- :remote-host server
- :remote-port port)
- (let ((n (array-total-size buf)))
- (setf (fill-pointer buf) n)
- (multiple-value-bind (b len addr) (rw.socket:udp-receive s buf n)
- (declare (ignore addr))
- ;;(print (list :@@@ (subseq b 0 len)))
- (flet ((cb (pos)
- (next-$name (rw:skip (rw:reader b) pos))))
- (let ((*name-from-position* #'cb))
- (next-$message (rw:shorter-reader (rw:reader b) len))))))))
+ (let ((s (rw.socket:make-udp-socket)))
+ (rw.socket:using-socket
+ s
+ (lambda ()
+ (rw.socket:udp-send s buf (length buf)
+ :remote-host server
+ :remote-port port)
+ (let ((n (array-total-size buf)))
+ (setf (fill-pointer buf) n)
+ (multiple-value-bind (b len addr) (rw.socket:udp-receive s buf n)
+ (declare (ignore addr))
+ ;;(print (list :@@@ (subseq b 0 len)))
+ (flet ((cb (pos)
+ (next-$name (rw:skip (rw:reader b) pos))))
+ (let ((*name-from-position* #'cb))
+ (next-$message (rw:shorter-reader (rw:reader b) len))))))))))
(defun query1 (name server &key (type 'A) (class 'IN) (port 53))
(let* ((n 512) ;; TODO minus IP/UDP headers
diff --git a/os.lisp b/os.lisp
@@ -29,7 +29,7 @@
:md5sum
:run-command
:sha1sum
- :with-flock
+ :using-flock
:with-program-io
:with-program-output
:with-temporary-file))
@@ -336,12 +336,11 @@
(-1 (error "flock ~s ~s ~s failed with code ~s"
stream operation blockp (sb-alien:get-errno)))))
-(defun call-with-flock (pathname shared fn)
+(defun using-flock (pathname sharedp if-does-not-exist thunk)
+ (when (eq :create if-does-not-exist)
+ (open pathname :direction :probe :if-does-not-exist :create))
(with-open-file (s pathname
:direction :output
:if-exists :overwrite)
- (flock s (if shared :shared :exclusive) t)
- (funcall fn)))
-
-(defmacro with-flock ((pathname &key shared) &body body)
- `(call-with-flock ,pathname ,shared (lambda () ,@body)))
+ (flock s (if sharedp :shared :exclusive) t)
+ (funcall thunk)))
diff --git a/socket.lisp b/socket.lisp
@@ -30,12 +30,12 @@
:ipv6-address-string
:make-ipv4-address
:make-ipv6-address
- :make-tcp-server-socket
:make-tcp-client-socket
+ :make-tcp-server-socket
:make-udp-socket
:udp-receive
:udp-send
- :with-socket))
+ :using-socket))
(in-package :rw.socket)
@@ -268,13 +268,10 @@
#+(or ecl sbcl mkcl)
(sb-bsd-sockets:socket-close socket))
-(defun call-with-socket (socket fn)
- (unwind-protect (funcall fn socket)
+(defun using-socket (socket thunk)
+ (unwind-protect (funcall thunk)
(close-socket socket)))
-(defmacro with-socket ((var socket) &body body)
- `(call-with-socket ,socket (lambda (,var) ,@body)))
-
(defun make-tcp-server-socket (local-host local-port &key backlog)
#-(or allegro clisp sbcl ecl mkcl cmucl ccl)
(error "RW.SOCKET:MAKE-TCP-SERVER-SOCKET not ported")
diff --git a/ui.lisp b/ui.lisp
@@ -157,17 +157,19 @@
(defparameter *session-lifespan* (* 60 60))
(defun make-session (sid create construct)
- (let ((lock (rw.concurrency:make-lock "session ~s"))
- (touched (get-universal-time))
- (stepper (make-stepper sid create construct)))
+ (let ((l (rw.concurrency:make-lock "session ~s"))
+ (n (get-universal-time))
+ (s (make-stepper sid create construct)))
(lambda (aid)
- (rw.concurrency:with-lock (lock)
- (cond
- ((eq t aid)
- (< (- (get-universal-time) touched) *session-lifespan*))
- (t
- (setq touched (get-universal-time))
- (funcall stepper aid)))))))
+ (rw.concurrency:using-lock
+ l
+ (lambda ()
+ (cond
+ ((eq t aid)
+ (< (- (get-universal-time) n) *session-lifespan*))
+ (t
+ (setq n (get-universal-time))
+ (funcall s aid))))))))
(defun rd (cnt)
(let ((s *standard-input*))
@@ -199,29 +201,31 @@
(rd 4))))
(defun make-pool ()
- (let ((sessions (make-hash-table :test #'equal))
- (lock (rw.concurrency:make-lock "pool ~s")))
+ (let ((s (make-hash-table :test #'equal))
+ (l (rw.concurrency:make-lock "pool ~s")))
(lambda (create construct deconstruct)
(multiple-value-bind (sid aid *renv*) (funcall deconstruct)
(let ((aid2 (parse36 aid))) ;; number=action|string=resource
(when aid2
(setq aid aid2)))
(funcall
- (rw.concurrency:with-lock (lock)
- (maphash (lambda (k v)
- (unless (funcall v t)
- (remhash k sessions)))
- sessions)
- (let ((x (and sid aid (gethash sid sessions))))
- (if x
- (lambda () (funcall x aid))
- (do ()
- ((not (gethash (setq sid (generate-sid)) sessions))
- (setf (gethash sid sessions)
- (make-session sid create construct))
- (lambda ()
- (http-redirect
- (funcall construct sid (pretty36 0) *renv*)))))))))))))
+ (rw.concurrency:using-lock
+ l
+ (lambda ()
+ (maphash (lambda (k v)
+ (unless (funcall v t)
+ (remhash k s)))
+ s)
+ (let ((x (and sid aid (gethash sid s))))
+ (if x
+ (lambda () (funcall x aid))
+ (do ()
+ ((not (gethash (setq sid (generate-sid)) s))
+ (setf (gethash sid s)
+ (make-session sid create construct))
+ (lambda ()
+ (http-redirect
+ (funcall construct sid (pretty36 0) *renv*))))))))))))))
(defparameter *pool* (make-pool))