From d4006339f7c9ff7a775240fe251e151015d60899 Mon Sep 17 00:00:00 2001 From: cxxxr Date: Wed, 15 Jul 2026 14:09:06 +0900 Subject: [PATCH] fix(server): don't busy-wait for the first client login The editor thread's initialize callback spun in a bare (loop :until ready) until the first client called "login", pinning one CPU core at 100% from startup. On a deployed server with no connected client, the process burned a full core indefinitely. Replace the busy-wait flag with a semaphore so the editor thread blocks in wait-on-semaphore instead of spinning. Signaling more than once (e.g. on client reconnect) is harmless. Measured with the websocket server idle before login: before: editor thread at ~93% CPU after: editor thread at ~0% CPU, login still unblocks it Co-Authored-By: Claude Fable 5 --- frontends/server/main.lisp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/server/main.lisp b/frontends/server/main.lisp index 005f74f3b..22545579e 100644 --- a/frontends/server/main.lisp +++ b/frontends/server/main.lisp @@ -213,16 +213,16 @@ the same immutable instance for every subsequent message." args))) (defmethod lem-if:invoke ((jsonrpc jsonrpc) function) - (let ((ready nil)) + (let ((ready (bt2:make-semaphore :name "lem-server ready"))) (setf (jsonrpc-editor-thread jsonrpc) (funcall function (lambda () - (loop :until ready)))) + (bt2:wait-on-semaphore ready)))) (jsonrpc:expose (jsonrpc-server jsonrpc) "login" (login jsonrpc (lambda () - (setf ready t)))) + (bt2:signal-semaphore ready)))) (jsonrpc:expose (jsonrpc-server jsonrpc) "input" (lambda (args)