Nikodemus Siivola wrote:
> I bet what is happening is this:
>
> 1. Thread 1 asserts that value is a number, and writes it to table
> under the key.
>
> 2. Thread 2 calls REMHASH with the same key and table (somewhere else
> in the code.)
>
> 3. Thread 1 tries to read the value back from the table, and discovers
> it gone. Ooops.
>
> Having the table synchronized doesn't magically guarantee that the
> (SETF GETHASH) and GETHASH calls in the above segment are executed
> without other threads operating on the table.
>
> Use WITH-LOCKED-HASH-TABLE to group multiple read/write operations on
> a single hash-table:
>
> (with-locked-hash-table (ht)
> (assert (numberp value))
> (setf (gethash key ht) value)
> (assert (numberp (gethash key ht))))
>
> guarantees that the second ASSERT will not fail if the first on did
> not. Assuming the table is synchronized, this excludes not only other
> WITH-LOCKED-HASH-TABLE sections using the same table, but all of (SETF
> GETHASH), GETHASH, CLRHASH, and REMHASH for the duration.
>
What I found surprising is that there is no REMHASH anywhere in my code;
the threads just write to that hash table, and the values are always
numbers, so once an entry contains a number, that number might change
but never disappear. Or so I thought.
So, if I understand what you are saying:
1. thread 1 writes to the table
2. thread 2 wants to write to that same key, and this, it seems, implies
first removing the former entry and then creating a new one; sometimes
it happens that thread 1 reads from the table in between these two
operations, and finds nothing.
Is that correct?
giovanni
|