mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 01:39:19 +08:00
GP-7051 - Fixed deadlock seen when saving a program
This commit is contained in:
+37
-14
@@ -26,7 +26,6 @@ import ghidra.program.model.util.VoidPropertyMap;
|
|||||||
*/
|
*/
|
||||||
public class PersistentOpenCloseManager implements OpenCloseManager {
|
public class PersistentOpenCloseManager implements OpenCloseManager {
|
||||||
private boolean openByDefault = true;
|
private boolean openByDefault = true;
|
||||||
private VoidPropertyMap booleanProperty;
|
|
||||||
private ProgramUserData programUserData;
|
private ProgramUserData programUserData;
|
||||||
|
|
||||||
// Often, isOpen will be called on the same function address many times in a row so cache
|
// Often, isOpen will be called on the same function address many times in a row so cache
|
||||||
@@ -35,32 +34,53 @@ public class PersistentOpenCloseManager implements OpenCloseManager {
|
|||||||
private boolean cachedResult;
|
private boolean cachedResult;
|
||||||
private String defaultOpenClosePropertyname;
|
private String defaultOpenClosePropertyname;
|
||||||
|
|
||||||
|
private String owner;
|
||||||
|
private String propertyName;
|
||||||
|
private VoidPropertyMap cachedPropertyMap;
|
||||||
|
|
||||||
public PersistentOpenCloseManager(ProgramUserData data, String owner, String propertyName) {
|
public PersistentOpenCloseManager(ProgramUserData data, String owner, String propertyName) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.propertyName = propertyName;
|
||||||
this.defaultOpenClosePropertyname = propertyName + "Default";
|
this.defaultOpenClosePropertyname = propertyName + "Default";
|
||||||
programUserData = data;
|
programUserData = data;
|
||||||
|
|
||||||
int tx = programUserData.startTransaction();
|
|
||||||
try {
|
|
||||||
booleanProperty =
|
|
||||||
programUserData.getBooleanProperty(owner, propertyName, true);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
programUserData.endTransaction(tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the default open state. Only addresses different from default have properties stored.
|
// Get the default open state. Only addresses different from default have properties stored.
|
||||||
String functionState =
|
String functionState =
|
||||||
programUserData.getStringProperty(defaultOpenClosePropertyname, "Open");
|
programUserData.getStringProperty(defaultOpenClosePropertyname, "Open");
|
||||||
openByDefault = functionState.equals("Open");
|
openByDefault = functionState.equals("Open");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private VoidPropertyMap getExistingProperty() {
|
||||||
|
if (cachedPropertyMap != null) {
|
||||||
|
return cachedPropertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedPropertyMap = programUserData.getBooleanProperty(owner, propertyName, false);
|
||||||
|
return cachedPropertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VoidPropertyMap getOrCreatePropertyMap() {
|
||||||
|
if (cachedPropertyMap != null) {
|
||||||
|
return cachedPropertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedPropertyMap = programUserData.getBooleanProperty(owner, propertyName, true);
|
||||||
|
return cachedPropertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen(Address address) {
|
public boolean isOpen(Address address) {
|
||||||
|
VoidPropertyMap propertyMap = getExistingProperty();
|
||||||
|
if (propertyMap == null) {
|
||||||
|
return openByDefault;
|
||||||
|
}
|
||||||
|
|
||||||
if (address.equals(cachedAddress)) {
|
if (address.equals(cachedAddress)) {
|
||||||
return cachedResult;
|
return cachedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedAddress = address;
|
cachedAddress = address;
|
||||||
boolean contains = booleanProperty.hasProperty(address);
|
boolean contains = propertyMap.hasProperty(address);
|
||||||
cachedResult = openByDefault ? !contains : contains;
|
cachedResult = openByDefault ? !contains : contains;
|
||||||
return cachedResult;
|
return cachedResult;
|
||||||
}
|
}
|
||||||
@@ -111,7 +131,8 @@ public class PersistentOpenCloseManager implements OpenCloseManager {
|
|||||||
private void addAddressProperty(Address address) {
|
private void addAddressProperty(Address address) {
|
||||||
int tx = programUserData.startTransaction();
|
int tx = programUserData.startTransaction();
|
||||||
try {
|
try {
|
||||||
booleanProperty.add(address);
|
VoidPropertyMap propertyMap = getOrCreatePropertyMap();
|
||||||
|
propertyMap.add(address);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
programUserData.endTransaction(tx);
|
programUserData.endTransaction(tx);
|
||||||
@@ -121,7 +142,8 @@ public class PersistentOpenCloseManager implements OpenCloseManager {
|
|||||||
private void removeAddressProperty(Address address) {
|
private void removeAddressProperty(Address address) {
|
||||||
int tx = programUserData.startTransaction();
|
int tx = programUserData.startTransaction();
|
||||||
try {
|
try {
|
||||||
booleanProperty.remove(address);
|
VoidPropertyMap propertyMap = getOrCreatePropertyMap();
|
||||||
|
propertyMap.remove(address);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
programUserData.endTransaction(tx);
|
programUserData.endTransaction(tx);
|
||||||
@@ -131,7 +153,8 @@ public class PersistentOpenCloseManager implements OpenCloseManager {
|
|||||||
private void clearProperties() {
|
private void clearProperties() {
|
||||||
int tx = programUserData.startTransaction();
|
int tx = programUserData.startTransaction();
|
||||||
try {
|
try {
|
||||||
booleanProperty.clear();
|
VoidPropertyMap propertyMap = getOrCreatePropertyMap();
|
||||||
|
propertyMap.clear();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
programUserData.endTransaction(tx);
|
programUserData.endTransaction(tx);
|
||||||
|
|||||||
Reference in New Issue
Block a user