Skip to content

Commit 34cda6f

Browse files
committed
fixed join bug
1 parent 5e5fe58 commit 34cda6f

File tree

3 files changed

+45
-38
lines changed

3 files changed

+45
-38
lines changed

test/basic.lisp

+14-13
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,18 @@
133133
(is (= 3 (ask :my-counter 2)))
134134
(close-actor :my-counter))
135135

136-
;; TODO sometimes fails checking registry after join.
137-
;; not really a big deal but it should be fixed.
138-
139-
;; I need to create a Join Sync signal I think...
140-
141-
;; (deftest test-close-and-join ()
142-
;; (define-actor counter ((c 0)) (increment)
143-
;; (incf c increment))
136+
(deftest test-close-and-join ()
137+
(define-actor counter ((c 0)) (increment)
138+
(incf c increment))
144139

145-
;; (counter :name :my-counter)
146-
;; (send :my-counter 1)
147-
;; (is (= 3 (ask :my-counter 2)))
148-
;; (close-and-join-actors :my-counter)
149-
;; (is (eql nil (gethash :my-counter *registry*))))
140+
(counter :name :my-counter)
141+
(send :my-counter 1)
142+
(print "asking")
143+
(force-output)
144+
(is (= 3 (ask :my-counter 2)))
145+
(print "joining")
146+
(force-output)
147+
(close-and-join-actors :my-counter)
148+
(print "checking")
149+
(force-output)
150+
(is (eql nil (gethash :my-counter *registry*))))

test/fuzz.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
:thespis/test/basic
99
:stream (make-broadcast-stream)))))
1010

11-
(deftest fuzz-dispatcher-tests (&optional (times 16))
11+
(deftest fuzz-dispatcher-tests (&optional (times 8))
1212
"Don't try as many reps here because it is too slow."
1313
(dotimes (i times)
1414
(is (fiasco:run-tests

thespis.lisp

+30-24
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
(defvar *registry* (make-hash-table))
66

7+
(define-condition unregister (condition) ())
8+
79
(defstruct close-signal)
810

911
(defstruct async-signal
@@ -26,8 +28,7 @@
2628
(defstruct dispatcher
2729
(name nil :type (or nil symbol keyword))
2830
(workers nil :type list)
29-
(openp t :type boolean)
30-
(lock (bt2:make-lock) :type bt2:lock))
31+
(openp t :type boolean))
3132

3233
(defgeneric resolve-actor (actor)
3334
(:method ((actor dispatcher))
@@ -46,18 +47,21 @@
4647

4748
(defmethod run-actor ((actor actor))
4849
"Run main event loop for actor."
49-
(loop (let ((sig (q:qpop (actor-queue actor))))
50-
(etypecase sig
51-
(async-signal
52-
(process-message actor (async-signal-msg sig)))
53-
(sync-signal
54-
(process-message actor (sync-signal-msg sig))
55-
(bt2:signal-semaphore (sync-signal-sem sig)))
56-
(close-signal
57-
(remhash (actor-name actor) *registry*)
58-
(return-from run-actor))
59-
(null
60-
(bt2:wait-on-semaphore (actor-sem actor)))))))
50+
(handler-case
51+
(loop (let ((sig (q:qpop (actor-queue actor))))
52+
(etypecase sig
53+
(async-signal
54+
(process-message actor (async-signal-msg sig)))
55+
(sync-signal
56+
(process-message actor (sync-signal-msg sig))
57+
(bt2:signal-semaphore (sync-signal-sem sig)))
58+
(close-signal
59+
(signal (make-instance 'unregister)))
60+
(null
61+
(bt2:wait-on-semaphore (actor-sem actor))))))
62+
(unregister (c)
63+
(declare (ignore c))
64+
(remhash (actor-name actor) *registry*))))
6165

6266
(defmethod send-signal ((actor actor) sig)
6367
(unless (actor-openp actor)
@@ -69,12 +73,13 @@
6973
(:documentation "Send a close-signal to an actor.")
7074
(:method ((actor actor))
7175
(send-signal actor (make-close-signal))
72-
(setf (actor-openp actor) nil))
76+
(setf (actor-openp actor) nil)
77+
actor)
7378
(:method ((actor dispatcher))
74-
(remhash (dispatcher-name actor) *registry*)
7579
(dolist (worker (dispatcher-workers actor))
7680
(close-actor worker))
77-
(setf (dispatcher-openp actor) nil))
81+
(setf (dispatcher-openp actor) nil)
82+
actor)
7883
(:method ((actor t))
7984
(close-actor (resolve-actor actor))))
8085

@@ -84,24 +89,25 @@
8489
(bt2:join-thread (actor-thread actor))
8590
(apply #'values (actor-store actor)))
8691
(:method ((actor dispatcher))
87-
(mapcar #'join-actor (dispatcher-workers actor)))
92+
(prog1 (mapcar #'join-actor (dispatcher-workers actor))
93+
(remhash (dispatcher-name actor) *registry*)))
8894
(:method ((actor t))
8995
(join-actor (resolve-actor actor))))
9096

9197
(defgeneric destroy-actor (actor)
9298
(:documentation "Immediately destroy an actor's thread.")
9399
(:method ((actor actor))
94-
(remhash (actor-name actor) *registry*)
95-
(bt2:destroy-thread (actor-thread actor)))
100+
(bt2:interrupt-thread (actor-thread actor)
101+
(lambda ()
102+
(signal (make-instance 'unregister)))))
96103
(:method ((actor dispatcher))
97-
(remhash (dispatcher-name actor) *registry*)
98-
(mapcar #'destroy-actor (dispatcher-workers actor)))
104+
(prog1 (mapcar #'destroy-actor (dispatcher-workers actor))
105+
(remhash (dispatcher-name actor) *registry*)))
99106
(:method ((actor t))
100107
(destroy-actor (resolve-actor actor))))
101108

102109
(defun close-and-join-actors (&rest actors)
103-
(mapc #'close-actor actors)
104-
(mapcar #'join-actor actors))
110+
(mapcar #'join-actor (mapcar #'close-actor actors)))
105111

106112
(defgeneric send (actor &rest args)
107113
(:documentation "Asyncronously send a message to an actor.")

0 commit comments

Comments
 (0)