From 127d52da68e4aefcdc1ba8f432d5767ebb8fbb4b Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 22 Oct 2026 13:04:13 +0100 Subject: [PATCH 1/2] VDBObject : Mitigate lack of thread safety in `hash()` This made lots of interesting sequences of events possible - here's one : 1. Thread A sees `m_hashValid == false` and starts to compute the hash. 2. Thread B also sees `m_hashValid == false` and also starts to compute the hash. 3. Threads A and B merrily stomp over `m_hash` concurrently, so the result won't be deterministic. There are further problems though... 4. Thread A finishes stomping and sets `m_hashValid = true`. Thread B continues stomping. 5. Threads C, D, E etc see `m_hashValid == true` and read whatever the current value of `m_hash` is - all getting different values from different stages of thread B's stomping. This was causing instanced in-memory VDBS to lose their instancing when exported to Arnold, because each instance got a different random version of the hash. This is mitigated by computing the hash in a temporary variable before assigning it. This isn't a full fix though, because the compiler _could_ reorder `m_hashValid = true` before `m_hash = h` from the point of view of a reading thread. Solving that needs some form of synchronisation (mutex, call_once etc), which we can't do without an ABI break. --- src/IECoreVDB/VDBObject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/IECoreVDB/VDBObject.cpp b/src/IECoreVDB/VDBObject.cpp index 41b09d6328..d4449bf805 100644 --- a/src/IECoreVDB/VDBObject.cpp +++ b/src/IECoreVDB/VDBObject.cpp @@ -424,11 +424,12 @@ openvdb::GridBase::Ptr VDBObject::HashedGrid::grid() const IECore::MurmurHash VDBObject::HashedGrid::hash() const { + /// \todo This is not threadsafe. Fix it. if( !m_hashValid ) { - m_hash = IECore::MurmurHash(); + IECore::MurmurHash h; - MurmurHashSink sink( m_hash ); + MurmurHashSink sink( h ); boost::iostreams::stream hashStream( sink ); openvdb::io::StreamMetadata::Ptr streamMetadata ( new openvdb::io::StreamMetadata() ); @@ -439,6 +440,7 @@ IECore::MurmurHash VDBObject::HashedGrid::hash() const m_grid->writeBuffers( hashStream ); m_grid->writeTransform( hashStream ); + m_hash = h; m_hashValid = true; } From a3fec1a2ae30294f5382b5fd858416811e86da71 Mon Sep 17 00:00:00 2001 From: ivanimanishi Date: Thu, 22 Oct 2026 15:48:20 -0700 Subject: [PATCH 2/2] Bump version to 10.5.18.2 --- Changes | 10 +++++++++- SConstruct | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index 5053279e0b..ae32797428 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,14 @@ -10.5.x.x (relative to 10.5.18.1) +10.5.x.x (relative to 10.5.18.2) ======== +10.5.18.2 (relative to 10.5.18.1) +======== + +Fixes +----- + +- VDB : Mitigated lack of thread safety in `hash()` + 10.5.18.1 (relative to 10.5.18.0) ======== diff --git a/SConstruct b/SConstruct index 2009706062..bcac6be15a 100644 --- a/SConstruct +++ b/SConstruct @@ -55,7 +55,7 @@ SConsignFile() ieCoreMilestoneVersion = 10 # for announcing major milestones - may contain all of the below ieCoreMajorVersion = 5 # backwards-incompatible changes ieCoreMinorVersion = 18 # new backwards-compatible features -ieCorePatchVersion = 1 # bug fixes +ieCorePatchVersion = 2 # bug fixes ieCoreVersionSuffix = "" # used for alpha/beta releases. Example: "a1", "b2", etc. ###########################################################################################