Merge remote-tracking branch

'origin/GP-774-dragonmacher-dt-manager-deadlock--SQUASHED' (Closes
#2832)
This commit is contained in:
ghidra1 2021-03-15 17:55:26 -04:00
commit 28138bcba2

View file

@ -1695,34 +1695,41 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
@Override @Override
public void disassociate(DataType dataType) { public void disassociate(DataType dataType) {
UniversalID oldDtID = dataType.getUniversalID();
SourceArchive sourceArchive = dataType.getSourceArchive();
sourceArchive = resolveSourceArchive(sourceArchive);
UniversalID id = sourceArchive == null ? DataTypeManager.LOCAL_ARCHIVE_UNIVERSAL_ID
: sourceArchive.getSourceArchiveID();
if (id.equals(getUniversalID())) {
id = DataTypeManager.LOCAL_ARCHIVE_UNIVERSAL_ID;
}
if (id == DataTypeManager.LOCAL_ARCHIVE_UNIVERSAL_ID) {
// Already local data type so no source archive associated.
return;
}
// Set the source archive to null indicating no associated archive. lock.acquire();
dataType.setSourceArchive(null); try {
UniversalID oldDtID = dataType.getUniversalID();
SourceArchive sourceArchive = dataType.getSourceArchive();
sourceArchive = resolveSourceArchive(sourceArchive);
UniversalID id = sourceArchive == null ? DataTypeManager.LOCAL_ARCHIVE_UNIVERSAL_ID
: sourceArchive.getSourceArchiveID();
if (id.equals(getUniversalID())) {
id = DataTypeManager.LOCAL_ARCHIVE_UNIVERSAL_ID;
}
if (id == DataTypeManager.LOCAL_ARCHIVE_UNIVERSAL_ID) {
// Already local data type so no source archive associated.
return;
}
// Set the datatype's universal ID to a newly generated universal ID, // Set the source archive to null indicating no associated archive.
// since we no longer want the source archive data type's universal ID. dataType.setSourceArchive(null);
if (dataType instanceof DataTypeDB) {
DataTypeDB dt = (DataTypeDB) dataType; // Set the datatype's universal ID to a newly generated universal ID,
dt.setUniversalID(UniversalIdGenerator.nextID()); // since we no longer want the source archive data type's universal ID.
if (dataType instanceof DataTypeDB) {
DataTypeDB dt = (DataTypeDB) dataType;
dt.setUniversalID(UniversalIdGenerator.nextID());
}
if (oldDtID != null) {
idsToDataTypeMap.removeDataType(sourceArchive, oldDtID);
}
dataTypeChanged(dataType);
} }
finally {
if (oldDtID != null) { lock.release();
idsToDataTypeMap.removeDataType(sourceArchive, oldDtID);
} }
dataTypeChanged(dataType);
} }
private Collection<DataType> filterOutNonSourceSettableDataTypes( private Collection<DataType> filterOutNonSourceSettableDataTypes(
@ -2694,9 +2701,10 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
try { try {
creatingDataType++; creatingDataType++;
DBRecord record = functionDefAdapter.createRecord(name, funDef.getComment(), cat.getID(), DBRecord record =
DEFAULT_DATATYPE_ID, funDef.hasVarArgs(), funDef.getGenericCallingConvention(), functionDefAdapter.createRecord(name, funDef.getComment(), cat.getID(),
sourceArchiveIdValue, universalIdValue, funDef.getLastChangeTime()); DEFAULT_DATATYPE_ID, funDef.hasVarArgs(), funDef.getGenericCallingConvention(),
sourceArchiveIdValue, universalIdValue, funDef.getLastChangeTime());
FunctionDefinitionDB funDefDb = FunctionDefinitionDB funDefDb =
new FunctionDefinitionDB(this, dtCache, functionDefAdapter, paramAdapter, record); new FunctionDefinitionDB(this, dtCache, functionDefAdapter, paramAdapter, record);
@ -3696,7 +3704,13 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
@Override @Override
public DataType getDataType(SourceArchive sourceArchive, UniversalID datatypeID) { public DataType getDataType(SourceArchive sourceArchive, UniversalID datatypeID) {
UniversalID sourceID = sourceArchive == null ? null : sourceArchive.getSourceArchiveID(); UniversalID sourceID = sourceArchive == null ? null : sourceArchive.getSourceArchiveID();
return idsToDataTypeMap.getDataType(sourceID, datatypeID); lock.acquire();
try {
return idsToDataTypeMap.getDataType(sourceID, datatypeID);
}
finally {
lock.release();
}
} }
@Override @Override
@ -3829,7 +3843,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
monitor.setProgress(0); monitor.setProgress(0);
monitor.setMaximum(orderedComposites.size()); monitor.setMaximum(orderedComposites.size());
monitor.setMessage("Updating Datatype Sizes..."); monitor.setMessage("Updating Datatype Sizes...");
int count = 0; int count = 0;
for (CompositeDB c : orderedComposites) { for (CompositeDB c : orderedComposites) {
monitor.checkCanceled(); monitor.checkCanceled();
@ -4162,7 +4176,11 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
Map<UniversalID, DataType> idMap = Map<UniversalID, DataType> idMap =
map.computeIfAbsent(sourceID, k -> new ConcurrentHashMap<>()); map.computeIfAbsent(sourceID, k -> new ConcurrentHashMap<>());
final UniversalID sourceArchiveID = sourceID; UniversalID sourceArchiveID = sourceID;
// note: this call is atomic and has a lock on the 'idMap'. It may call to a method
// that requires a db lock. As such, the call to computeIfAbsent() must be
// made while holding the db lock.
return idMap.computeIfAbsent(dataTypeID, return idMap.computeIfAbsent(dataTypeID,
k -> findDataTypeForIDs(sourceArchiveID, dataTypeID)); k -> findDataTypeForIDs(sourceArchiveID, dataTypeID));
} }