[ 
https://issues.apache.org/jira/browse/GEODE-9033?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17308242#comment-17308242
 ] 

Darrel Schneider commented on GEODE-9033:
-----------------------------------------

I looked at the code that sets the value field and all the version stamp fields 
and I think the spin solution can work.
The value field is volatile. The version stamp fields are not but, at least in 
EntryEventImpl.setNewValueInRegion, it first sets the version stamp fields (by 
calling generateAndSetVersionTag) and then sets the value field (by calling 
setValueWithTombstoneCheck). The java memory model ensures that what was 
visible to a thread that wrote a volatile field will be visible to another 
thread after it reads the volatile field. So our spin logic would be to first 
read the value (the volatile field). Then we can read the version stamp fields 
and know that we are seeing the version stamp values from the thread that set 
the value or a later thread (I think it is possible for non-volatile fields to 
read later values, it just isn't guaranteed). So we can then turn around and 
read the value again followed by the version stamp again. If the version stamp 
has not changed then we can safely say we read it and the FIRST value we read.
At first I thought we could just read the value a second time and see if it 
changed. The problem with that is it is possible to writes set the value field 
to the exact same value but change the version stamp. In that case we need to 
make sure and get the most recent version stamp.
We also need to look at all the other places in the code that call 
generateAndSetVersionTag to make sure it is called BEFORE the value field is 
updated.


> client read operations should not be blocked by a write operation
> -----------------------------------------------------------------
>
>                 Key: GEODE-9033
>                 URL: https://issues.apache.org/jira/browse/GEODE-9033
>             Project: Geode
>          Issue Type: Improvement
>          Components: client/server
>    Affects Versions: 1.1.0
>            Reporter: Darrel Schneider
>            Priority: Major
>
> Client read operations currently will be blocked by a write operation that is 
> in progress.
> This is caused by the write operation holding a synchronization on the 
> RegionEntry and LocalRegion.getDeserializedValue synchronizing the 
> RegionEntry with clientEvent is not null in order to atomically obtain both 
> the entry's value and version.
> The read code in LocalRegion that causes this is:
> {code:java}
>           synchronized (regionEntry) {
>             // value & version must be obtained atomically
>             
> clientEvent.setVersionTag(regionEntry.getVersionStamp().asVersionTag());
>             value = getDeserialized(regionEntry, updateStats, 
> disableCopyOnRead,
>                 preferCachedDeserializable, retainResult);
>           }
> {code}
> To fix this it may be possible to change the write operations to synchronize 
> on something else while changing both the value and version (but not while 
> doing anything else). Then the read code can sync on that new Object and not 
> the RegionEntry instance.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to