Re: Race condition on loading packages from 2 maxima processes in parallel?

David Scherfgen via Maxima-discuss <[email protected]> Sun, 14 Jun 2026 16:00:19 +0200
Newsgroups gmane.comp.mathematics.maxima.general
Message-ID <CAMTHLKiZmNN_SmdQjzYsRHA9M5mnC8G9Gjgdror7YrF_9mXg7g@mail.gmail.com>
Gemini proposed this Common Lisp file locking mechanism (but read below):

(defmacro with-file-lock ((lock-file &key (sleep-time 0.1)) &body body)
  "Acquires an exclusive lock using purely ANSI Common Lisp atomic file
creation."
  (let ((stream-sym (gensym "STREAM")))
    `(let ((,stream-sym nil))
       (unwind-protect
           (progn
             ;; Spinlock: keep trying to create the file until successful
             (loop
               (handler-case
                   (progn
                     (setf ,stream-sym (open ,lock-file
                                             :direction :output
                                             :if-exists :error
                                             :if-does-not-exist :create))
                     (return)) ; Successfully acquired lock; exit the loop
                 (file-error ()
                   ;; Lock file exists; wait and retry
                   (sleep ,sleep-time))))
             ;; Execute the compilation or protected code
             ,@body)
         ;; Cleanup: close the stream and delete the lock file
         (when ,stream-sym
           (close ,stream-sym)
           (ignore-errors (delete-file ,lock-file)))))))

I tried it by having multiple processes do this:

(with-file-lock (".lockfile") (format t "Entered~%") (sleep 30) (format t
"Exited~%"))

Seems to work ...
There could be a problem, though, when a process crashes / gets killed
while it has the lock. Then it won't release the lock, and no process could
ever acquire it again.
In theory, one could define a "timeout" and say that if the lockfile exists
and is too old (check using file-write-date), then the process probably
crashed.
For a robust solution, one should use e.g. POSIX flock.

Best regards
David Scherfgen

Am So., 14. Juni 2026 um 15:40 Uhr schrieb Raymond Toy <
[email protected]>:

> On 6/14/26 5:05 AM, Gunter Königsmann via Maxima-discuss wrote:
>
> Dear all,
>
> wxMaxima on every commit creates a new virtual machine, compiles wxMaxima
> in that machine and runs a few hundred tests in that machine.
>
> If it runs more than one test in parallel sometimes maxima fails to load
> draw.
>
> My theory is:
>
>    - One maxima process tries to load draw, compiles that package and
>    starts saving it.
>    - A second maxima process tries to load the compiled draw package
>    while that compiled package still being written.
>
> Could that be the case?
>
> Yes. Look at share/draw/draw.lisp. It runs mk:oos to compile all the
> files from the draw package.
> &#8203;
> _______________________________________________
> Maxima-discuss mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/maxima-discuss
>

_______________________________________________
Maxima-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/maxima-discuss