Re: Hash table thread safety

"Tim Bradshaw (as tfb at tfeb dot org)" <[email protected]>
Newsgroups gmane.lisp.lispworks.general
Message-ID <[email protected]>
On 31 Mar 2026, at 10:20, Yuri Davidovsky <[email protected]> wrote:

> If you need to perform multiple operations atomically (e.g., incrementing a value stored in the table), SBCL provides a specific macro to hold the table's internal lock:
> 
> (sb-ext:with-locked-hash-table (my-table)
>   (let ((val (gethash key my-table)))
>     (setf (gethash key my-table) (1+ val))))

LW has WITH-HASH-TABLE-LOCKED, which I have never used but I assume is designed to deal with just this case.

I've also always rather liked macros like

(defmacro atomically (&body forms)
  ;; Not safe in interpreted code I am sure
  `(with-lock ((load-time-value (make-lock :name "Atomic" :recursivep t)))
     ,@forms))))

although I'm sure there are other cases where this isn't safe.

> If you truly do not need atomicity for your logic but only the guarantee that the table won't break — SBCL's :synchronized t is still the mandatory flag to prevent crashes.

I think what I need is in fact something like (a) things won't break and (b) if thread a says (setf (gethash k h) v1) and thread b says (setf (gethash k h) v2) h ends up with an entry for k with value v1 or v2, and in particular not no entry or any other value.  With that, the thing can still end up with orphans, but it can collect those (if you ask it to).

--tim

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
[email protected]
http://www.lispworks.com/support/lisp-hug.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.