1

With a function that calls an asynchronous process, it's possible to call the same function multiple times.

What is a reliable way to avoid this that properly handles quit and errors being raised?

Is there an lisp convention for how to handle this?


This is an example of locking function, I'm wondering if there are better ways to handle this (existing macros or conventions for e.g).

(defvar my-fn--lock nil)

(defun my-fn ()
  (unless my-fn--lock
    (unwind-protect
        (progn
          (setq my-fn--lock t)

          ;; Code body.
          (do-stuff))

      ;; Protected.
      (setq my-fn--lock nil))))
1
  • What you've done, and what @phils suggested, are the ways I've seen this kind of thing done. And what you did is the more common approach, I think. (It's not specific to function invocation, for example; it's used for testing whether some code has already been loaded or executed.)
    – Drew
    Mar 30, 2020 at 1:08

2 Answers 2

0

I'd probably use a symbol property: function-put to add or release the lock on the function symbol, and function-get to query the state.

Tangentially, C-h i g (elisp)Mutexes is a thing; but that's not what you're looking for here.

2
  • Could you show an example of how this would work?
    – ideasman42
    Mar 30, 2020 at 4:29
  • Just like your approach, but instead of (setq my-fn--lock VALUE) you would (function-put 'my-fn 'NAME VALUE) and instead of evaluating my-fn--lock you would (function-get 'my-fn 'NAME) (for whatever arbitrary NAME you chose). It just means you're not defining a separate variable which isn't used in any other context.
    – phils
    Mar 31, 2020 at 6:24
0

This can be done using unwind-protect, this example shows how it can be done in a macro:

;; Generic macro:

(defmacro with-lock-var (var &rest body)
  "Set VAR to t while in the scope of BODY, use to implement locking."
  (declare (indent 1))
  `
  (unwind-protect
    (progn
      (setq ,var t)
      ,@body)

    ;; Protected.
    (setq ,var nil)))


;; Example use:

(defvar my-fn--lock nil)

(defun my-fn ()
  (unless my-fn--lock
    (with-lock-var
      ;; Code body.
      (do-stuff))))

Your Answer

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

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