source: branches/new-datamodel/src/threading/reader-writer.lisp

Last change on this file was 230, checked in by lgiessmann, 15 years ago

fixed ticket #68 --> http://trac.common-lisp.net/isidorus/ticket/68

  • Property svn:eol-style set to native
File size: 2.1 KB
Line 
1;;+-----------------------------------------------------------------------------
2;;+  Isidorus
3;;+  (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
4;;+
5;;+  Isidorus is freely distributable under the LGPL license.
6;;+  You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
7;;+-----------------------------------------------------------------------------
8
9
10(defpackage :isidorus-threading
11  (:use :cl :bordeaux-threads)
12  (:export :current-readers
13           :with-reader-lock
14           :with-writer-lock))
15
16(in-package :isidorus-threading)
17
18(defvar *readerlist-lock* (make-lock "isidorus-threading: current readers lock"))
19(defvar *writer-lock* (make-lock "isidorus-threading: writer lock"))
20(defvar *current-readers* nil)
21
22
23(defun current-readers ()
24  "Returns a copy of the list which contains all current reader
25   threads, *current-readers*"
26  (let ((result nil))
27    (with-lock-held (*readerlist-lock*)
28      (setf result (copy-list *current-readers*)))
29    result))
30
31
32(defun add-thread-to-reader-list ()
33  "Adds the current thread to the reader list"
34  (with-lock-held (*writer-lock*)
35    (with-lock-held (*readerlist-lock*)
36      (push (current-thread) *current-readers*))))
37
38
39(defun remove-thread-from-reader-list ()
40  "Removes the current threads from the reader list"
41  (with-lock-held (*readerlist-lock*)
42    (setf *current-readers*
43          (delete (current-thread) *current-readers*))))
44
45
46(defmacro with-reader-lock (&body body)
47  "Executes the passed 'body' with the reader lock"
48  `(progn
49     (add-thread-to-reader-list)
50     (let ((result nil))
51       (handler-case
52           (setf result ,@body)
53         (condition (c)
54           (progn
55             (remove-thread-from-reader-list)
56             (error c))))
57       (remove-thread-from-reader-list)
58       result)))
59
60
61(defmacro with-writer-lock (&body body)
62  "Executes the passed body when the reader list is empty otherwise
63   the do macor loops in 500 ms time interval for a next chance."
64  `(with-lock-held (*writer-lock*)
65     (do
66      ((remaining-readers (current-readers) (current-readers)))
67      ((null remaining-readers))
68       (sleep 0.05))
69     ,@body))
Note: See TracBrowser for help on using the repository browser.