diff --git a/src/main/java/net/openhft/chronicle/hash/ChecksumEntry.java b/src/main/java/net/openhft/chronicle/hash/ChecksumEntry.java
index 1ed32abb9..b3b652c5e 100644
--- a/src/main/java/net/openhft/chronicle/hash/ChecksumEntry.java
+++ b/src/main/java/net/openhft/chronicle/hash/ChecksumEntry.java
@@ -32,6 +32,13 @@ public interface ChecksumEntry {
* only when value bytes was updated directly, for example though flyweight implementation of
* a value
* interface.
+ *
+ * @throws UnsupportedOperationException if checksums are not stored in the containing Chronicle
+ * Hash
+ * @throws RuntimeException if the context of this entry is locked improperly, e. g. on the
+ * {@linkplain HashQueryContext#readLock() read} level, that is not upgradable to the
+ * {@linkplain HashQueryContext#updateLock() update} level. Calling {@code updateChecksum()}
+ * method is enabled when at least update lock is held.
*/
void updateChecksum();
@@ -39,6 +46,12 @@ public interface ChecksumEntry {
* Computes checksum from the entry bytes and checks whether it is equal to the stored checksum.
*
* @return {@code true} if stored checksum equals to checksum computed from the entry bytes
+ * @throws UnsupportedOperationException if checksums are not stored in the containing Chronicle
+ * Hash
+ * @throws RuntimeException if the context of this entry is locked improperly, e. g. on the
+ * {@linkplain HashQueryContext#readLock() read} level, that is not upgradable to the
+ * {@linkplain HashQueryContext#updateLock() update} level. Calling {@code checkSum()} method is
+ * enabled when at least update lock is held.
*/
boolean checkSum();
}
diff --git a/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/HashEntryStages.java b/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/HashEntryStages.java
index cc437d1d7..18cc8a0a3 100644
--- a/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/HashEntryStages.java
+++ b/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/HashEntryStages.java
@@ -164,6 +164,7 @@ public abstract class HashEntryStages implements HashEntry, ChecksumEntry
throw new UnsupportedOperationException(
"Checksum is not stored in this Chronicle Hash");
}
+ s.innerUpdateLock.lock();
initDelayedUpdateChecksum(true);
}
@@ -174,6 +175,10 @@ public abstract class HashEntryStages implements HashEntry, ChecksumEntry
throw new UnsupportedOperationException(
"Checksum is not stored in this Chronicle Hash");
}
+ // This is needed, because a concurrent update lock holder might perform an entry update,
+ // but not yet written a checksum (because checksum write is delayed to the update unlock).
+ // So checkSum() on read lock level might result to false negative results.
+ s.innerUpdateLock.lock();
return delayedUpdateChecksumInit() || checksumStrategy.innerCheckSum();
}