]> git.pond.sub.org Git - eow/blobdiff - locked-queue.lisp
Add thread safe queue. Use to push updates to client.
[eow] / locked-queue.lisp
diff --git a/locked-queue.lisp b/locked-queue.lisp
new file mode 100644 (file)
index 0000000..66f4354
--- /dev/null
@@ -0,0 +1,35 @@
+(in-package :locked-queue)
+
+(declaim (optimize (space 0) (speed 0) (safety 3) (debug 3)))
+
+(defclass locked-queue ()
+  ((queue :initform nil)
+   (mutex :initform (sb-thread:make-mutex :name "queue lock"))
+   (waitq :initform (make-waitqueue))))
+
+(defun create ()
+  (make-instance 'locked-queue))
+
+(defmethod dequeue ((q locked-queue))
+  (with-slots (queue mutex waitq) q
+    (with-mutex (mutex)
+      (if (or (null queue)
+             (null (first queue)))
+         (condition-wait waitq mutex))
+      (prog1 (first (car queue))
+       (setf (car queue)
+             (rest (car queue)))))))
+
+(defmethod enqueue ((q locked-queue) value)
+  (with-slots (queue mutex waitq) q
+    (with-mutex (mutex)
+      (let ((last (list value)))
+       (if (null (first queue))
+           (progn
+             (setf queue (cons last last))
+             (condition-notify waitq))
+           (progn
+             (setf (rest (cdr queue))
+                   last
+                   (cdr queue) last)
+             (cons (car queue) last)))))))