summaryrefslogtreecommitdiff
path: root/bin/emacsclient
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-10-24 13:53:47 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-10-29 21:47:37 -0700
commit82a13b897f279d9ba5882fb181cc912bbd51b482 (patch)
tree41d030a4434b61b4bff0158ef0b9d4835095db18 /bin/emacsclient
parente7d9f3ba91a80516cfef93821532f1d7d9436338 (diff)
downloaddotfiles-82a13b897f279d9ba5882fb181cc912bbd51b482.tar.gz
emacsclient wrapper: add locking around starting up daemons
Diffstat (limited to 'bin/emacsclient')
-rwxr-xr-xbin/emacsclient36
1 files changed, 31 insertions, 5 deletions
diff --git a/bin/emacsclient b/bin/emacsclient
index 20e243c7..ed1c2215 100755
--- a/bin/emacsclient
+++ b/bin/emacsclient
@@ -33,7 +33,9 @@ status=
daemon_name=
gdbmacs=
args=
-socket_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/emacs/"
+xdg="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
+socket_dir="$xdg/emacs/"
+locks_dir="$xdg/spw_emacsclient/"
get_listener () {
local socket="$1"
@@ -53,6 +55,15 @@ maybe_notify () {
&& notify-send --urgency=low --expire-time=10000 "$1"
}
+spw_flock () {
+ mkdir -p "$locks_dir"
+ eval "exec $1<>${locks_dir}$2"
+ if ! flock --wait 15 "$1"; then
+ maybe_notify "couldn't lock starting Emacs daemon named $2"
+ exit 1
+ fi
+}
+
die_wedged () {
maybe_notify "in-tree Emacs appears to be wedged"
# Only exit non-zero if we were expected to start the daemon.
@@ -92,6 +103,8 @@ installed_emacsclient=$(PATH=$(echo "$PATH" \
command -v ss >/dev/null || exec "$installed_emacsclient" -a "" "$@"
+$want_version || spw_flock 3 "${daemon_name:-server}"
+
socket="$socket_dir${daemon_name:-server}"
listener="$(get_listener $socket)"
if [ -n "$listener" ]; then
@@ -138,6 +151,7 @@ if ! $want_installed && ! $installed_running \
# ---- Two special cases for primary session that's always under gdb
if [ -z "$daemon_name" ] && ! $want_version; then
+ spw_flock 4 gdbmacs
# If devel Emacs is stopped or gdbmacs can't start it, ask gdbmacs to
# handle the request: it's probs. C-i e or editing a file via EDITOR.
@@ -162,8 +176,9 @@ if ! $want_installed && ! $installed_running \
--exclude "$(egrep_negate ${socket_dir}server)" &
inotifywait=$!
- if "$installed_emacsclient" -a '' -sgdbmacs \
- --eval '(spw/gdbmacs-attach)'; then
+ if "$installed_emacsclient" \
+ -a '' -sgdbmacs \
+ --eval '(spw/gdbmacs-attach)' 3>&- 4>&-; then
wait $inotifywait
listener=true
elif $want_eval || $want_update; then
@@ -178,9 +193,11 @@ if ! $want_installed && ! $installed_running \
if $pass_to_gdbmacs; then
emacs="$installed_emacs"
emacsclient="$installed_emacsclient"
+ socket="${socket_dir}gdbmacs"
listener="$gdbmacs"
set -- "$@" -sgdbmacs
fi
+ exec 4>&-
fi
# ---- End two special cases for primary session that's always under gdb
else
@@ -210,12 +227,21 @@ if $want_update && [ -n "$listener" ]; then
--eval "(spw/update-environment$args))"
fi
+maybe_hold_lock () {
+ # Hold on to the lock until daemon has started up.
+ $want_version || [ -n "$listener" ] \
+ || inotifywait -qq -e create "${socket_dir}" \
+ --exclude "$(egrep_negate $socket)" &
+}
+
# emacsclient(1) requires an argument. As a special case, if there are no
# arguments except -s/--socket-name, and no daemon is running, just start one.
# And if there were no arguments but we were requested just to update env
# vars, exit peacefully.
if [ "$#" -eq "$min_arg" -a -z "$listener" ]; then
- exec "$emacs" --daemon"${daemon_name:+=$daemon_name}"
+ maybe_hold_lock
+ exec "$emacs" --daemon"${daemon_name:+=$daemon_name}" 3>&-
elif ! ( [ "$#" -eq "$min_arg" ] && $want_update ); then
- exec "$emacsclient" -a "" "$@"
+ maybe_hold_lock
+ exec "$emacsclient" -a "" "$@" 3>&-
fi