-
Notifications
You must be signed in to change notification settings - Fork 2
/
moira.lisp
72 lines (64 loc) · 1.97 KB
/
moira.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
;;;; moira.lisp
(in-package #:moira)
;;; "moira" goes here. Hacks and glory await!
(declaim (type list *monitored-threads*))
(defvar *monitored-threads* '())
(defun list-monitored-threads ()
*monitored-threads*)
(defun clear-monitored-threads ()
(synchronized ('*monitored-threads*)
(nix *monitored-threads*)))
(defclass monitored-thread (serapeum:synchronized)
((thread
:initform nil
:type a-thread
:reader monitored-thread.thread)
(done
:initform nil
:type boolean
:reader monitored-thread.donep)
(thunk
:initarg :thunk
:type function
:reader monitored-thread.thunk)
(name
:initarg :name
:type string
:reader monitored-thread.name)))
(defmethods monitored-thread (self thread thunk name done)
(:method print-object (self stream)
(print-unreadable-object (self stream :type t)
(format stream name)
(when done
(format stream " (done)"))))
(:method initialize-instance :after (self &key)
(synchronized ('*monitored-threads*)
(pushnew self *monitored-threads*)))
(:method start (self)
(etypecase-of a-thread thread
((or no-thread dead-thread)
(setf done nil
thread (make-thread-and-wait
(lambda ()
(funcall thunk)
(synchronized (self)
(setf done t)))
:name name)))
(live-thread (error "Thread is running: ~a" thread))))
(:method stop (self)
(etypecase-of a-thread thread
((or no-thread dead-thread)
(nix thread))
(live-thread
(bt:destroy-thread (nix thread)))))
(:method ensure-alive (self)
(synchronized (self)
(if done
(progn
(synchronized ('*monitored-threads*)
(removef *monitored-threads* self))
(stop self))
(etypecase-of a-thread thread
(live-thread (values))
((or no-thread dead-thread)
(start self)))))))