[Q] Unscheduling a timer in its expiry function
Hello All,
Can an expiry function for a timer unschedule the timer? This is not
clear from the documentation, but in the test code below, it doesn't
work.
----------------
(in-package "CL-USER")
(defvar *test-timer* nil)
(defvar *test-count* 0)
(defun test-callback (stream)
(princ "ding!" stream)
(cond ((< *test-count* 5)
(incf *test-count*))
((>= *test-count* 5)
(princ " dong! " stream)
(mp:unschedule-timer *test-timer*)))
(terpri stream))
(progn
(setq *test-timer* (mp:make-timer #'test-callback *standard-output*))
(setq *test-count* 0)
(mp:schedule-timer *test-timer* 0 1))
;; Use the following to unschedule the timer
;;
(mp:unschedule-timer *test-timer*)
----------------
Eval'ing the PROGN, ought to kick off the timer, and after five calls
to TEST-CALLBACK, I was expecting the timer to be unscheduled.
I looked in some of the CAPI examples (notably pong.lisp) and I found
some code as follows:
(defun play-game (self)
:
:
(setf timer (mp:make-timer 'make-a-pong-move self))
(mp:schedule-timer timer 0 delay))
MAKE-A-PONG-MOVE is the timer expiry function.
(defun make-a-pong-move (self)
(unless (capi-internals:representation self)
(with-slots (timer) self
(when timer
(mp:unschedule-timer timer)))
(return-from make-a-pong-move nil))
:
:
)
But, I'm not sure if and under what circumstances this code is
actually exercised. There are also other places in the code where, a
call to UNSCHEDULE-TIMER is made but within the scope of a
CAPI:EXECUTE-WITH-INTERFACE, which presumably occurs in the CAPI
thread and will work as expected.
If it's not possible to unschedule a timer from within it's expiry
function, then what is a recommended way to do this without
sacrificing abstraction.
Thanks,
-ram