3

When running a function inside a timer, there are some constraints on whats possible.


Is it possible to detect if a function is running from a timer so an alternate code-path can be used?

The only solution I've found is to add advice on the caller to define a variable which the function being called can check, however this isn't such a nice solution as it may mean adding advice to many functions.

3
  • 1
    I guess you can see it from the call stack, which you can loop through with mapbacktrace. Commented Sep 5, 2022 at 12:05
  • @Gilles'SO-stopbeingevil' : Is that viable at runtime? How does a (non-debugger) Lisp program go about obtaining the current call stack? Commented Sep 7, 2022 at 13:26
  • @PhilHudson Lisp programs don't need any official “debugger” blessing to call mapbacktrace. It will miss frames that are optimized away by the byte compiler, but that wouldn't matter here. Commented Sep 7, 2022 at 17:34

1 Answer 1

2

All timers get processed in timer-event-handler, so you can add advice to that instead:

(defvar called-by-timer nil
  "Bound to t when a function is called by a timer.")

(advice-add 'timer-event-handler :around
            (lambda (oldfun &rest args)
              (let ((called-by-timer t))
                (apply oldfun args))))

(defun hello ()
  (message "%s %s" "Hello" (if called-by-timer "from timer" "from elsewhere")))

(hello)
(run-with-timer 1 nil #'hello)
1
  • Should hello not also unset called-by-timer on exit? Commented Sep 7, 2022 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.