Skip to content

Commit e9b8a94

Browse files
committed
Don't complain if multiple threads are trying to hash an MRTG.
1 parent 4f12825 commit e9b8a94

File tree

1 file changed

+43
-12
lines changed

1 file changed

+43
-12
lines changed

typed_python/MutuallyRecursiveTypeGroup.cpp

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,11 @@ std::string MutuallyRecursiveTypeGroup::repr(bool deep) {
161161

162162
std::string levelPrefix(level, ' ');
163163

164-
s << levelPrefix << "group with hash " << group->hash().digestAsHexString() << ":\n";
164+
if (group->mIsCurrentlyHashing) {
165+
s << levelPrefix << "hashing group @ " << (void*)group << "\n";
166+
} else {
167+
s << levelPrefix << "group with hash " << group->hash().digestAsHexString() << ":\n";
168+
}
165169

166170
// sort lexically and then by level, so that
167171
// we can tell what's going on when we have a discrepancy
@@ -188,16 +192,25 @@ std::string MutuallyRecursiveTypeGroup::repr(bool deep) {
188192
subgroup = v.typeOrPyobjAsType()->getRecursiveTypeGroup();
189193
ixInSubgroup = v.typeOrPyobjAsType()->getRecursiveTypeGroupIndex();
190194
} else {
191-
std::tie(subgroup, ixInSubgroup) = MutuallyRecursiveTypeGroup::pyObjectGroupHeadAndIndex(
192-
v.typeOrPyobjAsObject()
193-
);
195+
std::tie(subgroup, ixInSubgroup) =
196+
MutuallyRecursiveTypeGroup::pyObjectGroupHeadAndIndex(
197+
v.typeOrPyobjAsObject()
198+
);
194199
}
195200

196201
if (seen.find(subgroup) == seen.end()) {
197202
dump(subgroup, level + 2);
198203
} else {
199-
s << levelPrefix << " " << "group with hash " << group->hash().digestAsHexString()
200-
<< " item " << ixInSubgroup << "\n";
204+
if (group->mIsCurrentlyHashing) {
205+
s << levelPrefix << " "
206+
<< "hashing group @ " << (void*)group
207+
<< " item " << ixInSubgroup << "\n";
208+
} else {
209+
s << levelPrefix << " "
210+
<< "group with hash "
211+
<< group->hash().digestAsHexString()
212+
<< " item " << ixInSubgroup << "\n";
213+
}
201214
}
202215
}
203216
}
@@ -465,19 +478,34 @@ void MutuallyRecursiveTypeGroup::computeHash() {
465478
return;
466479
}
467480

468-
if (mIsCurrentlyHashing) {
481+
PyEnsureGilAcquired getTheGil;
482+
483+
thread_local static std::unordered_set<MutuallyRecursiveTypeGroup*> hashingGroupsSet;
484+
thread_local static std::vector<MutuallyRecursiveTypeGroup*> hashingGroups;
485+
486+
if (hashingGroupsSet.find(this) != hashingGroupsSet.end()) {
469487
CompilerVisibleObjectVisitor::singleton().checkForInstability();
470488

471-
throw std::runtime_error(
472-
"Somehow we are already computing the hash of this MRTG. "
489+
std::ostringstream errMsg;
490+
491+
errMsg << "Somehow we are already computing the hash of this MRTG. "
473492
"This means that when we computed the group's constituents, we missed "
474-
"a link between elements of this group and elements of a calling group."
475-
);
493+
"a link between elements of this group and elements of a calling group.\n\n";
494+
495+
for (auto group: hashingGroups) {
496+
errMsg << group->repr(false) << "\n\n";
497+
}
498+
499+
errMsg << this->repr(false) << "\n";
500+
501+
throw std::runtime_error(errMsg.str());
476502
}
477503

478504
try {
479505
// mark that we're currently hashing.
480506
mIsCurrentlyHashing = true;
507+
hashingGroups.push_back(this);
508+
hashingGroupsSet.insert(this);
481509

482510
// we are a recursive group head. We want to compute the hash
483511
// of all of our constituents where, when each of them looks at
@@ -504,13 +532,16 @@ void MutuallyRecursiveTypeGroup::computeHash() {
504532
mHash = wholeGroupHash;
505533
mIsCurrentlyHashing = false;
506534

507-
PyEnsureGilAcquired getTheGil;
535+
hashingGroups.pop_back();
536+
hashingGroupsSet.erase(this);
508537

509538
if (mHashToGroup.find(mHash) == mHashToGroup.end()) {
510539
mHashToGroup[mHash] = this;
511540
}
512541
} catch(...) {
513542
mIsCurrentlyHashing = false;
543+
hashingGroups.pop_back();
544+
hashingGroupsSet.erase(this);
514545
throw;
515546
}
516547
}

0 commit comments

Comments
 (0)