Lisp HUG Maillist Archive

Thread safety and with-slots

Let's say I have a variable X in a class that is accessed from multiple threads (written and read). I have a lock in the class as well. I'd like to know if this is safe...

(with-slots (x lock)
    my-object
  (with-lock (lock)
    (setf x 10)))

Or does the with-lock have to encompass the with-slots?

Jeff M.

Re: Thread safety and with-slots

Hi Jeffrey,

I believe that if you examine the macro expansion, you'll find that the with-slots merely sets up accessors for the slots based on the object specified following the list of slots. There is no read / write action until you actually try to reference a slot. So you should be safe.

just my 2-cents...

- DM


On Sep 3, 2013, at 11:53 AM, Jeffrey Massung <massung@gmail.com> wrote:

Let's say I have a variable X in a class that is accessed from multiple threads (written and read). I have a lock in the class as well. I'd like to know if this is safe...

(with-slots (x lock)
    my-object
  (with-lock (lock)
    (setf x 10)))

Or does the with-lock have to encompass the with-slots?

Jeff M.

Dr. David McClain
dbm@refined-audiometrics.com



Re: Thread safety and with-slots

On 3 Sep 2013, at 19:53, Jeffrey Massung wrote:

Let's say I have a variable X in a class that is accessed from multiple threads (written and read). I have a lock in the class as well. I'd like to know if this is safe...

(with-slots (x lock)
    my-object
  (with-lock (lock)
    (setf x 10)))


I hate questions like this because they make me think!  I think WITH-SLOTS has to set up symbol macros which read & write the actual slots, rather than writing at the end, because it can't know who else knows about the instance, so almost any function called during the dynamic extent of WITH-SLOTS might expect to look at the slots of the object and see the updated values.  And this is true independently of multithreading

Something like this:

(defvar *stash*)

(defun foo ()
  (slot-value *stash* 'slot))

(defun bar (o)
  (with-slots (slot) o
    (setf slot 12)
    (prog1 
        (foo)
      (setf slot 10))))

(defun outer (o)
  (let ((*stash* o))
    (bar o)))
    

(outer (make-instance ....))


Updated at: 2020-12-10 08:35 UTC