mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
GP-4531 Corrected Ghidra Server deadlock
This commit is contained in:
parent
bf01521402
commit
feaf8e2d49
@ -36,18 +36,20 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
|
||||
implements RemoteBufferFileHandle, Unreferenced {
|
||||
|
||||
// Tracks open handles by user repository connection: maps repository handle instance to list of open file handles
|
||||
private static HashMap<RemoteRepositoryHandle, List<RemoteBufferFileImpl>> instanceOwnerMap =
|
||||
private static final HashMap<RemoteRepositoryHandle, List<RemoteBufferFileImpl>> instanceOwnerMap =
|
||||
new HashMap<>();
|
||||
|
||||
// Tracks open handles by path: maps "repo-name:<file-path>" to list of open buffer file handles
|
||||
private static HashMap<String, List<RemoteBufferFileImpl>> instancePathMap = new HashMap<>();
|
||||
private static final HashMap<String, List<RemoteBufferFileImpl>> instancePathMap =
|
||||
new HashMap<>();
|
||||
|
||||
protected final RepositoryHandleImpl owner;
|
||||
protected final String associatedFilePath;
|
||||
|
||||
private LocalBufferFile bufferFile;
|
||||
private final String clientHost;
|
||||
private final LocalBufferFile bufferFile;
|
||||
|
||||
private boolean disposed = false;
|
||||
private String clientHost;
|
||||
|
||||
/**
|
||||
* Construct a remote wrapper for a buffer file.
|
||||
@ -68,7 +70,6 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
|
||||
}
|
||||
this.clientHost = RepositoryManager.getRMIClient();
|
||||
addInstance(this);
|
||||
//System.out.println("Constructed remote buffer file (" + instanceID + "): " + bufferFile);
|
||||
}
|
||||
|
||||
private static String getFilePathKey(RemoteBufferFileImpl rbf) {
|
||||
@ -95,7 +96,6 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
|
||||
instancePathMap.put(filePathKey, list);
|
||||
}
|
||||
list.add(rbf);
|
||||
rbf.owner.fireOpenFileCountChanged();
|
||||
}
|
||||
|
||||
private static synchronized void removeOwnerInstance(RemoteBufferFileImpl rbf) {
|
||||
@ -104,7 +104,6 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
|
||||
if (list.isEmpty()) {
|
||||
instanceOwnerMap.remove(rbf.owner);
|
||||
}
|
||||
rbf.owner.fireOpenFileCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +117,29 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose and unexport all RemoteBufferFileImpl instances associated with the
|
||||
* specified owner.
|
||||
* @param owner
|
||||
* @return true if one or more buffer files were disposed.
|
||||
*/
|
||||
public static synchronized boolean dispose(Object owner) {
|
||||
boolean found = false;
|
||||
List<RemoteBufferFileImpl> list = instanceOwnerMap.remove(owner);
|
||||
if (list != null) {
|
||||
for (RemoteBufferFileImpl rbf : list) {
|
||||
found = true;
|
||||
rbf.dispose();
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
// If files were found, may need to repeat since pre-save
|
||||
// files may have been constructed during dispose
|
||||
dispose(owner);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of open RemoteBufferFileHandle's associated with the
|
||||
* specified owner repository handle.
|
||||
@ -172,46 +194,26 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose and unexport all RemoteBufferFileImpl instances associated with the
|
||||
* specified owner.
|
||||
* @param owner
|
||||
* @return true if one or more buffer files were disposed.
|
||||
*/
|
||||
public static synchronized boolean dispose(Object owner) {
|
||||
boolean found = false;
|
||||
List<RemoteBufferFileImpl> list = instanceOwnerMap.remove(owner);
|
||||
if (list != null) {
|
||||
for (RemoteBufferFileImpl rbf : list) {
|
||||
found = true;
|
||||
rbf.dispose();
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
// If files were found, may need to repeat since pre-save
|
||||
// files may have been constructed during dispose
|
||||
dispose(owner);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose associated buffer file and unexport this instance.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void dispose() {
|
||||
// must handle concurrent invocations
|
||||
if (!disposed) {
|
||||
try {
|
||||
unexportObject(this, true);
|
||||
public void dispose() {
|
||||
|
||||
removeOwnerInstance(this);
|
||||
removePathInstance(this);
|
||||
|
||||
synchronized (this) {
|
||||
if (!disposed) {
|
||||
try {
|
||||
unexportObject(this, true);
|
||||
}
|
||||
catch (NoSuchObjectException e) {
|
||||
// ignore
|
||||
}
|
||||
bufferFile.dispose();
|
||||
disposed = true;
|
||||
}
|
||||
catch (NoSuchObjectException e) {
|
||||
// ignore
|
||||
}
|
||||
removeOwnerInstance(this);
|
||||
removePathInstance(this);
|
||||
bufferFile.dispose();
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ import ghidra.util.exception.FileInUseException;
|
||||
* <code>RepositoryHandleImpl</code> provides a Repository handle to a
|
||||
* remote user.
|
||||
*/
|
||||
public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteRepositoryHandle,
|
||||
Unreferenced {
|
||||
public class RepositoryHandleImpl extends UnicastRemoteObject
|
||||
implements RemoteRepositoryHandle, Unreferenced {
|
||||
|
||||
// private final RepositoryChangeEvent NULL_EVENT = new RepositoryChangeEvent(
|
||||
// RepositoryChangeEvent.REP_NULL_EVENT, null, null, null, null);
|
||||
@ -191,8 +191,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
}
|
||||
|
||||
RepositoryChangeEvent openFileCountEvent =
|
||||
new RepositoryChangeEvent(RepositoryChangeEvent.REP_OPEN_HANDLE_COUNT, null, null,
|
||||
null, Integer.toString(RemoteBufferFileImpl.getOpenFileCount(this)));
|
||||
new RepositoryChangeEvent(RepositoryChangeEvent.REP_OPEN_HANDLE_COUNT, null, null, null,
|
||||
Integer.toString(RemoteBufferFileImpl.getOpenFileCount(this)));
|
||||
|
||||
synchronized (eventQueue) {
|
||||
if (clientActive) {
|
||||
@ -213,31 +213,6 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void fireOpenFileCountChanged() {
|
||||
// if (!isValid) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// RepositoryChangeEvent event =
|
||||
// new RepositoryChangeEvent(RepositoryChangeEvent.REP_OPEN_HANDLE_COUNT, null, null,
|
||||
// null, Integer.toString(RemoteBufferFileImpl.getOpenFileCount(this)));
|
||||
// synchronized (eventQueue) {
|
||||
//
|
||||
// // Remove existing queued event
|
||||
// Iterator<RepositoryChangeEvent> iterator = eventQueue.iterator();
|
||||
// while (iterator.hasNext()) {
|
||||
// RepositoryChangeEvent queuedEvent = iterator.next();
|
||||
// if (queuedEvent.type == RepositoryChangeEvent.REP_OPEN_HANDLE_COUNT) {
|
||||
// iterator.remove();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// eventQueue.add(event);
|
||||
// eventQueue.notifyAll();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryChangeEvent[] getEvents() throws IOException {
|
||||
synchronized (eventQueue) {
|
||||
@ -414,16 +389,15 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
if (folder == null) {
|
||||
throw new IOException("Failed to create repository Folder " + parentPath);
|
||||
}
|
||||
LocalManagedBufferFile bf =
|
||||
folder.createDatabase(itemName, fileID, bufferSize, contentType, currentUser,
|
||||
projectPath);
|
||||
LocalManagedBufferFile bf = folder.createDatabase(itemName, fileID, bufferSize,
|
||||
contentType, currentUser, projectPath);
|
||||
return new RemoteManagedBufferFileImpl(bf, this, getPathname(parentPath, itemName));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteManagedBufferFileImpl openDatabase(String parentPath, String itemName,
|
||||
int version, int minChangeDataVer) throws IOException {
|
||||
public RemoteManagedBufferFileImpl openDatabase(String parentPath, String itemName, int version,
|
||||
int minChangeDataVer) throws IOException {
|
||||
synchronized (syncObject) {
|
||||
validate();
|
||||
RepositoryFile rf = getFile(parentPath, itemName);
|
||||
@ -481,9 +455,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
validate();
|
||||
repository.validateWritePrivilege(currentUser);
|
||||
checkFolderInUse(oldParentPath, oldFolderName);
|
||||
RepositoryFolder folder =
|
||||
repository.getFolder(currentUser, oldParentPath + FileSystem.SEPARATOR +
|
||||
oldFolderName, false);
|
||||
RepositoryFolder folder = repository.getFolder(currentUser,
|
||||
oldParentPath + FileSystem.SEPARATOR + oldFolderName, false);
|
||||
RepositoryFolder newParent = repository.getFolder(currentUser, newParentPath, true);
|
||||
if (folder != null) {
|
||||
folder.moveTo(newParent, newFolderName, currentUser);
|
||||
@ -511,9 +484,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
}
|
||||
|
||||
private void checkFileInUse(String parentPath, String itemName) throws FileInUseException {
|
||||
String[] openFileUsers =
|
||||
RemoteBufferFileImpl.getOpenFileUsers(repository.getName(),
|
||||
getPathname(parentPath, itemName));
|
||||
String[] openFileUsers = RemoteBufferFileImpl.getOpenFileUsers(repository.getName(),
|
||||
getPathname(parentPath, itemName));
|
||||
if (openFileUsers != null) {
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (String user : openFileUsers) {
|
||||
@ -553,9 +525,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
if (rf.hasCheckouts()) {
|
||||
return true;
|
||||
}
|
||||
String[] openFileUsers =
|
||||
RemoteBufferFileImpl.getOpenFileUsers(repository.getName(),
|
||||
getPathname(folder.getPathname(), rf.getName()));
|
||||
String[] openFileUsers = RemoteBufferFileImpl.getOpenFileUsers(repository.getName(),
|
||||
getPathname(folder.getPathname(), rf.getName()));
|
||||
if (openFileUsers != null) {
|
||||
return true;
|
||||
}
|
||||
@ -622,7 +593,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCheckoutStatus[] getCheckouts(String parentPath, String itemName) throws IOException {
|
||||
public ItemCheckoutStatus[] getCheckouts(String parentPath, String itemName)
|
||||
throws IOException {
|
||||
synchronized (syncObject) {
|
||||
validate();
|
||||
RepositoryFile rf = getFile(parentPath, itemName);
|
||||
|
Loading…
Reference in New Issue
Block a user