-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsynchronized-bag.lisp
51 lines (45 loc) · 1.68 KB
/
synchronized-bag.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
;;;; synchronized-bag.lisp --- A bag that synchronizes accesses.
;;;;
;;;; Copyright (C) 2011-2016 Jan Moringen
;;;;
;;;; Author: Jan Moringen <[email protected]>
(cl:in-package #:rsbag)
(defclass synchronized-bag (bag)
((lock :reader bag-%lock
:initform (bt:make-lock "Bag lock")
:documentation
"The lock that is used to synchronized accesses to the
bag."))
(:documentation
"Instances of this bag class can be safely used from multiple
threads. Callers have to be prepared to encounter increased
latencies in comparison to the single-threaded case."))
(macrolet
((define-synchronized-method (name args)
`(defmethod ,name :around ,args
(bt:with-lock-held ((bag-%lock bag))
(call-next-method)))))
(define-synchronized-method close
((bag synchronized-bag)
&key &allow-other-keys))
(define-synchronized-method bag-channels
((bag synchronized-bag)))
(define-synchronized-method bag-channel
((bag synchronized-bag)
(name t)
&key &allow-other-keys))
(define-synchronized-method (setf bag-channel)
((new-value t)
(bag synchronized-bag)
(name t)
&key &allow-other-keys)))
(defmethod bag-channel-class ((bag synchronized-bag))
(load-time-value (find-class 'synchronized-channel) t))
(defmethod %make-channel ((bag synchronized-bag)
(name string)
(meta-data list)
(transform t)
&rest args &key)
(apply #'call-next-method
bag name meta-data transform
(append (list :lock (bag-%lock bag)) args)))