2

I want to override Emacs' default locking behavior to work in a noninteractive setting. To that end, when Emacs encounters a lock (as in file-locked-p), I would like it to wait patiently for the lock to disappear and then claim the file for itself. The naive implementation of such a scheme would look something like:

In theory, this should be achievable by overriding/advising ask-user-about-lock something like this:

(define-advice ask-user-about-lock (around (oldfun file opponent) wait-when-noninteractive)
  (if noninteractive
      ;; Non-interactive: wait for lock to disappear and then steal
      (prog1 t
        (while (stringp (file-locked-p file))
          (sit-for 1)))
    ;; Interactive: ask use as normal
    (funcall oldfun file opponent)))

However, I believe this creates a race condition, since multiple Emacs processes could be waiting on the same lock and if both notice the lock disappear, they will both attempt to claim the lock. Is there a better way to implement this behavior that won't create a race condition?

If anyone is curious why I want this, the reason is that my init file briefly locks a file during Emacs startup, and I have an Org-mode file that I would like to export to multiple formats asynchronously each time it is saved. Each async export job starts a new Emacs process, and each of these processes try to lock that same file during init, and all but one of them hang waiting for the user to tell them whether to steal the locked file. Having them simply wait and access the file one at a time instead would be idea.

1

Well, I wrote a package for it: https://github.com/DarwinAwardWinner/emacs-filelock

It provides a macro called filelock-with-lock which waits until it can acquire the lock on a file before executing some code. It should be just as resistant to race conditions as Emacs' native file locking mechanisms.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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