summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2025-10-24 09:05:12 +0300
committerGravatar Uko Kokņevičs2025-10-24 09:05:12 +0300
commitcf975709968ee26110514c779737bc80a5266e83 (patch)
tree7bce3f120e011ea0eb53c444b69df9038dfec5f1
parentConfigure a custom readtable explicitly (diff)
downloadukkoclot-main.tar.gz
ukkoclot-main.tar.xz
ukkoclot-main.zip
Use with-thunk in all my with- macrosHEADmain
-rw-r--r--TODO.org1
-rw-r--r--src/db.lisp19
-rw-r--r--src/rw-lock.lisp58
3 files changed, 50 insertions, 28 deletions
diff --git a/TODO.org b/TODO.org
index d37a824..41d3125 100644
--- a/TODO.org
+++ b/TODO.org
@@ -2,3 +2,4 @@
2* TODO See if I can rely on uiop more 2* TODO See if I can rely on uiop more
3* TODO See if I can rely on serapeum more 3* TODO See if I can rely on serapeum more
4* TODO Use function-cache to memoize stuff like bot-id, bot-username, get-my-name etc 4* TODO Use function-cache to memoize stuff like bot-id, bot-username, get-my-name etc
5* TODO Use clsql instead of cl-sqlite maybe
diff --git a/src/db.lisp b/src/db.lisp
index ea18d16..db8f7c1 100644
--- a/src/db.lisp
+++ b/src/db.lisp
@@ -3,8 +3,8 @@
3(defpackage :ukkoclot/src/db 3(defpackage :ukkoclot/src/db
4 (:use :c2cl :sqlite) 4 (:use :c2cl :sqlite)
5 (:import-from :log) 5 (:import-from :log)
6 (:import-from :serapeum :-> :defunion) 6 (:import-from :serapeum :-> :defunion :with-thunk)
7 (:export :inline-bot-type :blacklisted :whitelisted :get-inline-bot-type :set-inline-bot-type :with-db)) 7 (:export :inline-bot-type :blacklisted :whitelisted :get-inline-bot-type :set-inline-bot-type :call-with-db :with-db))
8(in-package :ukkoclot/src/db) 8(in-package :ukkoclot/src/db)
9 9
10(defconstant +target-version+ 1 10(defconstant +target-version+ 1
@@ -13,10 +13,19 @@
13(deftype db () 13(deftype db ()
14 'sqlite-handle) 14 'sqlite-handle)
15 15
16(-> call-with-db (pathname (function (db) t)) t)
17(defun call-with-db (path fn)
18 "Similar to `with-db', but instead of binding the database in a macro body,
19calls the function `fn' with it as an argument."
20 (let ((db (connect path)))
21 (unwind-protect (progn (upgrade db)
22 (funcall fn db))
23 (disconnect db))))
24
16(defmacro with-db ((name path) &body body) 25(defmacro with-db ((name path) &body body)
17 `(let ((,name (connect ,path))) 26 "Open database specified by `path' and bind it to `name' for the duration of the `body'."
18 (unwind-protect (progn (upgrade ,name) ,@body) 27 (with-thunk (body name)
19 (disconnect ,name)))) 28 `(call-with-db ,path ,body)))
20 29
21(defunion inline-bot-type 30(defunion inline-bot-type
22 blacklisted 31 blacklisted
diff --git a/src/rw-lock.lisp b/src/rw-lock.lisp
index 2a5e2c3..c0c545b 100644
--- a/src/rw-lock.lisp
+++ b/src/rw-lock.lisp
@@ -8,7 +8,7 @@
8 ;; These imports make this SBCL-dependent, but technically speaking we could live without them. 8 ;; These imports make this SBCL-dependent, but technically speaking we could live without them.
9 (:import-from :sb-sys 9 (:import-from :sb-sys
10 :allow-with-interrupts :with-local-interrupts :without-interrupts) 10 :allow-with-interrupts :with-local-interrupts :without-interrupts)
11 (:import-from :serapeum :->) 11 (:import-from :serapeum :-> :with-thunk)
12 (:import-from :ukkoclot/src/readtable :readtable) 12 (:import-from :ukkoclot/src/readtable :readtable)
13 (:export 13 (:export
14 #:rw-lock 14 #:rw-lock
@@ -16,9 +16,11 @@
16 #:make-rw-lock 16 #:make-rw-lock
17 #:acquire-read-lock 17 #:acquire-read-lock
18 #:release-read-lock 18 #:release-read-lock
19 #:call-with-read-lock
19 #:with-read-lock 20 #:with-read-lock
20 #:acquire-write-lock 21 #:acquire-write-lock
21 #:release-write-lock 22 #:release-write-lock
23 #:call-with-write-lock
22 #:with-write-lock)) 24 #:with-write-lock))
23(in-package :ukkoclot/src/rw-lock) 25(in-package :ukkoclot/src/rw-lock)
24(in-readtable readtable) 26(in-readtable readtable)
@@ -100,19 +102,24 @@
100 (wakeup-waiters rw-lock)))) 102 (wakeup-waiters rw-lock))))
101 rw-lock) 103 rw-lock)
102 104
105(-> call-with-read-lock (rw-lock (function () t)) t)
106(defun call-with-read-lock (rw-lock fn)
107 ;; TODO: timeout
108 "Similar to `with-read-lock', but instead of being a macro, it calls the function `fn'."
109 (let (lock-acquired)
110 (without-interrupts
111 (unwind-protect
112 (when (setf lock-acquired
113 (allow-with-interrupts (acquire-read-lock rw-lock)))
114 (with-local-interrupts (funcall fn)))
115 (when lock-acquired
116 (release-read-lock rw-lock))))))
117
103(defmacro with-read-lock ((rw-lock) &body body) 118(defmacro with-read-lock ((rw-lock) &body body)
104 ;; TODO: timeout 119 ;; TODO: timeout
105 (with-gensyms (lock-acquired lock-value) 120 "Hold the read lock for the duration of the `body'."
106 `(let ((,lock-acquired) 121 (with-thunk (body)
107 (,lock-value ,rw-lock)) 122 `(call-with-read-lock ,rw-lock ,body)))
108 (without-interrupts
109 (unwind-protect
110 (when (setf ,lock-acquired
111 (allow-with-interrupts
112 (acquire-read-lock ,lock-value)))
113 (with-local-interrupts ,@body))
114 (when ,lock-acquired
115 (release-read-lock ,lock-value)))))))
116 123
117(-> acquire-write-lock (rw-lock &key (:wait boolean)) boolean) 124(-> acquire-write-lock (rw-lock &key (:wait boolean)) boolean)
118(defun acquire-write-lock (rw-lock &key (wait t)) 125(defun acquire-write-lock (rw-lock &key (wait t))
@@ -149,16 +156,21 @@
149 (wakeup-waiters rw-lock))) 156 (wakeup-waiters rw-lock)))
150 rw-lock) 157 rw-lock)
151 158
159(-> call-with-write-lock (rw-lock (function () t)) t)
160(defun call-with-write-lock (rw-lock fn)
161 ;; TODO: timeout
162 "Similar to `with-write-lock', but instead of being a macro, it calls the function `fn'."
163 (let (lock-acquired)
164 (without-interrupts
165 (unwind-protect
166 (when (setf lock-acquired
167 (allow-with-interrupts (acquire-write-lock rw-lock)))
168 (with-local-interrupts (funcall fn)))
169 (when lock-acquired
170 (release-write-lock rw-lock))))))
171
152(defmacro with-write-lock ((rw-lock) &body body) 172(defmacro with-write-lock ((rw-lock) &body body)
153 ;; TODO: timeout 173 ;; TODO: timeout
154 (with-gensyms (lock-acquired lock-value) 174 "Hold the write lock for the duration of the `body'."
155 `(let ((,lock-acquired) 175 (with-thunk (body)
156 (,lock-value ,rw-lock)) 176 `(call-with-write-lock ,rw-lock ,body)))
157 (without-interrupts
158 (unwind-protect
159 (when (setf ,lock-acquired
160 (allow-with-interrupts
161 (acquire-write-lock ,lock-value)))
162 (with-local-interrupts ,@body))
163 (when ,lock-acquired
164 (release-write-lock ,lock-value)))))))