Skip to content

Commit 192aa75

Browse files
io_mapper: use multimap to track all observers per pin ID
Replace std::map with std::multimap for TObserverMap so all registered observers are tracked, not just the first. Update registerHandle() and both deregisterHandle() overloads to iterate all observers via equal_range() instead of accessing a single entry. This fixes a dangling-pointer risk where deregisterObserver() could not find and remove observers that were not first to register for a given ID. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
1 parent 02abc92 commit 192aa75

2 files changed

Lines changed: 16 additions & 11 deletions

File tree

core/include/forte/io/mapper/io_mapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace forte::io {
5151
typedef std::map<std::string, IOHandle *> THandleMap;
5252
THandleMap mHandles;
5353

54-
typedef std::map<std::string, IOObserver *> TObserverMap;
54+
typedef std::multimap<std::string, IOObserver *> TObserverMap;
5555
TObserverMap mObservers;
5656

5757
arch::CSyncObject mSyncMutex;

core/src/io/mapper/io_mapper.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ namespace forte::io {
4242

4343
DEVLOG_DEBUG("[IOMapper] Register handle %s\n", paId.c_str());
4444

45-
// Check for existing observer
46-
if (mObservers.find(paId) != mObservers.end()) {
47-
paHandle.onObserver(mObservers[paId]);
48-
mObservers[paId]->onHandle(&paHandle);
49-
45+
// Check for existing observers
46+
auto range = mObservers.equal_range(paId);
47+
for (auto obsIt = range.first; obsIt != range.second; ++obsIt) {
48+
paHandle.onObserver(obsIt->second);
49+
obsIt->second->onHandle(&paHandle);
5050
DEVLOG_INFO("[IOMapper] Connected %s\n", paId.c_str());
5151
}
5252

@@ -58,9 +58,12 @@ namespace forte::io {
5858

5959
for (auto it = mHandles.begin(); it != mHandles.end(); ++it) {
6060
if (it->second == &paHandle) {
61-
if (mObservers.find(it->first) != mObservers.end()) {
61+
auto range = mObservers.equal_range(it->first);
62+
if (range.first != range.second) {
6263
paHandle.dropObserver();
63-
mObservers[it->first]->dropHandle();
64+
for (auto obsIt = range.first; obsIt != range.second; ++obsIt) {
65+
obsIt->second->dropHandle();
66+
}
6467
DEVLOG_INFO("[IOMapper] Disconnected %s (lost handle)\n", it->first.data());
6568
}
6669

@@ -77,10 +80,12 @@ namespace forte::io {
7780

7881
auto handleIt = mHandles.find(paId);
7982
if (handleIt != mHandles.end()) {
80-
auto observerIt = mObservers.find(paId);
81-
if (observerIt != mObservers.end()) {
83+
auto range = mObservers.equal_range(paId);
84+
if (range.first != range.second) {
8285
handleIt->second->dropObserver();
83-
observerIt->second->dropHandle();
86+
for (auto obsIt = range.first; obsIt != range.second; ++obsIt) {
87+
obsIt->second->dropHandle();
88+
}
8489
DEVLOG_INFO("[IOMapper] Disconnected %s (lost handle)\n", paId.c_str());
8590
}
8691
DEVLOG_DEBUG("[IOMapper] Deregister handle %s\n", paId.c_str());

0 commit comments

Comments
 (0)