+mu4e-lock-available seems like a potential entry-point to the mu-lock functionality, e.g. on startup check if another Emacs process has mu4e active, and so it might as well be turned into an autoload.
94 lines
4.2 KiB
EmacsLisp
94 lines
4.2 KiB
EmacsLisp
;;; email/mu4e/autoload/mu-lock.el -*- lexical-binding: t; -*-
|
|
(autoload 'file-notify-rm-watch "filenotify")
|
|
(autoload 'file-notify-add-watch "filenotify")
|
|
|
|
(defvar +mu4e-lock-file (expand-file-name "mu4e_lock" temporary-file-directory)
|
|
"Location of the lock file which stores the PID of the process currenty running mu4e")
|
|
(defvar +mu4e-lock-request-file (expand-file-name "mu4e_lock_request" temporary-file-directory)
|
|
"Location of the lock file for which creating indicated that another process wants the lock to be released")
|
|
|
|
(defvar +mu4e-lock-greedy nil
|
|
"Whether to 'grab' the `+mu4e-lock-file' if nobody else has it, i.e. start Mu4e")
|
|
(defvar +mu4e-lock-relaxed t
|
|
"Whether if someone else wants the lock (signaled via `+mu4e-lock-request-file'), we should stop Mu4e and let go of it")
|
|
|
|
(defun +mu4e-lock-pid-info ()
|
|
"Get info on the PID refered to in `+mu4e-lock-file' in the form (pid . process-attributes)
|
|
If the file or process do not exist, the lock file is deleted an nil returned."
|
|
(when (file-exists-p +mu4e-lock-file)
|
|
(let* ((coding-system-for-read 'utf-8)
|
|
(pid (string-to-number
|
|
(with-temp-buffer
|
|
(insert-file-contents +mu4e-lock-file)
|
|
(buffer-string))))
|
|
(process (process-attributes pid)))
|
|
(if (and process (string-match-p "[Ee]macs" (alist-get 'comm process)))
|
|
(cons pid process)
|
|
(delete-file +mu4e-lock-file) nil))))
|
|
|
|
;;;###autoload
|
|
(defun +mu4e-lock-available (&optional strict)
|
|
"If the `+mu4e-lock-file' is available (unset or owned by this emacs) return t.
|
|
If STRICT only accept an unset lock file."
|
|
(not (when-let* ((lock-info (+mu4e-lock-pid-info))
|
|
(pid (car lock-info)))
|
|
(when (or strict (/= (emacs-pid) pid)) t))))
|
|
|
|
;;;###autoload
|
|
(defun +mu4e-lock-file-delete-maybe ()
|
|
"Check `+mu4e-lock-file', and delete it if this process is responsible for it."
|
|
(when (+mu4e-lock-available)
|
|
(delete-file +mu4e-lock-file)
|
|
(file-notify-rm-watch +mu4e-lock--request-watcher)))
|
|
|
|
;;;###autoload
|
|
(defun +mu4e-lock-start (orig-fun &optional callback)
|
|
"Check `+mu4e-lock-file', and if another process is responsible for it, abort starting.
|
|
Else, write to this process' PID to the lock file"
|
|
(unless (+mu4e-lock-available)
|
|
(call-process "touch" nil nil nil +mu4e-lock-request-file)
|
|
(message "Lock file exists, requesting that it be given up")
|
|
(sleep-for 0.1)
|
|
(delete-file +mu4e-lock-request-file))
|
|
(if (not (+mu4e-lock-available))
|
|
(user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time")
|
|
(write-region (number-to-string (emacs-pid)) nil +mu4e-lock-file)
|
|
(delete-file +mu4e-lock-request-file)
|
|
(call-process "touch" nil nil nil +mu4e-lock-request-file)
|
|
(funcall orig-fun callback)
|
|
(setq +mu4e-lock--request-watcher
|
|
(file-notify-add-watch +mu4e-lock-request-file
|
|
'(change)
|
|
#'+mu4e-lock-request))))
|
|
|
|
(defvar +mu4e-lock--file-watcher nil)
|
|
(defvar +mu4e-lock--file-just-deleted nil)
|
|
(defvar +mu4e-lock--request-watcher nil)
|
|
|
|
(defun +mu4e-lock-add-watcher ()
|
|
(setq +mu4e-lock--file-just-deleted nil)
|
|
(file-notify-rm-watch +mu4e-lock--file-watcher)
|
|
(setq +mu4e-lock--file-watcher
|
|
(file-notify-add-watch +mu4e-lock-file
|
|
'(change)
|
|
#'+mu4e-lock-file-updated)))
|
|
|
|
(defun +mu4e-lock-request (event)
|
|
"Handle another process requesting the Mu4e lock."
|
|
(when (equal (nth 1 event) 'created)
|
|
(when +mu4e-lock-relaxed
|
|
(mu4e--stop)
|
|
(file-notify-rm-watch +mu4e-lock--file-watcher)
|
|
(message "Someone else wants to use Mu4e, releasing lock")
|
|
(delete-file +mu4e-lock-file)
|
|
(run-at-time 0.2 nil #'+mu4e-lock-add-watcher))
|
|
(delete-file +mu4e-lock-request-file)))
|
|
|
|
(defun +mu4e-lock-file-updated (event)
|
|
(if +mu4e-lock--file-just-deleted
|
|
(+mu4e-lock-add-watcher)
|
|
(when (equal (nth 1 event) 'deleted)
|
|
(setq +mu4e-lock--file-just-deleted t)
|
|
(when (and +mu4e-lock-greedy (+mu4e-lock-available t))
|
|
(message "Noticed Mu4e lock was available, grabbed it")
|
|
(run-at-time 0.2 nil #'mu4e)))))
|