MCPcopy Create free account
hub / github.com/BehaviorTree/BehaviorTree.CPP / cloneInto

Method cloneInto

src/blackboard.cpp:180–271  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

178}
179
180void Blackboard::cloneInto(Blackboard& dst) const
181{
182 // We must never hold storage_mutex_ while locking entry_mutex, because
183 // the script evaluation path (ExprAssignment::evaluate) does the reverse:
184 // entry_mutex → storage_mutex_ (via entryInfo → getEntry).
185 //
186 // Strategy: collect shared_ptrs under storage_mutex_, release it,
187 // then copy entry data under entry_mutex only.
188
189 struct CopyTask
190 {
191 std::string key;
192 std::shared_ptr<Entry> src;
193 std::shared_ptr<Entry> dst; // nullptr when a new entry is needed
194 };
195
196 std::vector<CopyTask> tasks;
197 std::vector<std::string> keys_to_remove;
198
199 // Step 1: snapshot src/dst entries under both storage_mutex_ locks.
200 {
201 std::shared_lock lk1(storage_mutex_, std::defer_lock);
202 std::unique_lock lk2(dst.storage_mutex_, std::defer_lock);
203 std::lock(lk1, lk2);
204
205 std::unordered_set<std::string> dst_keys;
206 for(const auto& [key, entry] : dst.storage_)
207 {
208 dst_keys.insert(key);
209 }
210
211 for(const auto& [src_key, src_entry] : storage_)
212 {
213 dst_keys.erase(src_key);
214 auto it = dst.storage_.find(src_key);
215 if(it != dst.storage_.end())
216 {
217 tasks.push_back({ src_key, src_entry, it->second });
218 }
219 else
220 {
221 tasks.push_back({ src_key, src_entry, nullptr });
222 }
223 }
224
225 for(const auto& key : dst_keys)
226 {
227 keys_to_remove.push_back(key);
228 }
229 }
230 // storage_mutex_ locks released here
231
232 // Step 2: copy entry data under entry_mutex only (BUG-3 fix).
233 std::vector<std::pair<std::string, std::shared_ptr<Entry>>> new_entries;
234
235 for(auto& task : tasks)
236 {
237 if(task.dst)

Callers 3

BlackboardRestoreFunction · 0.80
BlackboardBackupFunction · 0.80
TESTFunction · 0.80

Calls 4

moveFunction · 0.85
push_backMethod · 0.80
endMethod · 0.45
emptyMethod · 0.45

Tested by 1

TESTFunction · 0.64