Merge remote-tracking branch 'origin/patch'

This commit is contained in:
Ryan Kurtz 2024-04-19 08:50:43 -04:00
commit 9abfa3da86
3 changed files with 79 additions and 93 deletions

View file

@ -259,25 +259,37 @@
<H2><A name="Disassociate_Data_Types"></A>Disassociating Data Types</H2> <H2><A name="Disassociate_Data_Types"></A>Disassociating Data Types</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P>You can arrive at the <I>Disassociate Data Types</I> <P>You can disassociate the source archive relationship for datatypes within a
dialog from the <B>Disassociate Datatypes From</B> specific archive/program by selecting the <B>Disassociate Datatypes From
action on an archive. The following dialog illustrates disassociating datatypes in a </B><IMG src="help/shared/arrow.gif"> <B>&lt;Source Archive Name&gt;</B>
program named <B>WinHelloCPP.exe</B> that originated popup action on the corresponding tree node within the
from a source archive named <B>MyArchive</B>.</P> <A HREF="data_type_manager_description.htm#Data_Type_Archives_Definition">Data Type Manager</A>.
If associated datatypes are found they will be listed in the <I>Disassociate Data Types</I>
dialog shown below. The sample case illustrates disassociating datatypes in a
program named <B>WinHelloCPP.exe</B> that originated from a source archive named
<B>MyArchive</B>.</P>
<P style="text-align: center;"><IMG alt="" src="images/DisassociateDialog.png"><BR> <P style="text-align: center;"><IMG alt="" src="images/DisassociateDialog.png"><BR>
</P> </P>
<P>The <I>Disassociate DataTypes</I> dialog <P>The <I>Disassociate DataTypes</I> dialog
displays a table that lists all the data types that are associated with a pariticular displays a table that lists all the data types that are associated with a pariticular
source archive. The table consists of the following columns:<BR> source archive. After selecting the datatypes to be disassociated from the source
archive, as reflected by the <B>Apply</B> column, the <B>Disassociate</B> button
may be clicked to complete the operation.</P>
<P><IMG src="help/shared/note.png">All datatypes may be selected for disassociation
by right-clicking on the table and choosing the <B>Select All</B> popup action.</P>
<P>The table consists of the following columns:<BR>
</P> </P>
<H4>Apply</H4> <H4>Apply</H4>
<BLOCKQUOTE> <BLOCKQUOTE>
<P>The apply checkbox. Selecting the checkbox will mark the data type to be <P>The apply checkbox. Selecting the checkbox will mark the data type to be
disassociated from the source archive.</P> disassociated from the source archive.
</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<H4>Status</H4> <H4>Status</H4>

View file

@ -36,18 +36,20 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
implements RemoteBufferFileHandle, Unreferenced { implements RemoteBufferFileHandle, Unreferenced {
// Tracks open handles by user repository connection: maps repository handle instance to list of open file handles // 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<>(); new HashMap<>();
// Tracks open handles by path: maps "repo-name:<file-path>" to list of open buffer file handles // 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 RepositoryHandleImpl owner;
protected final String associatedFilePath; protected final String associatedFilePath;
private LocalBufferFile bufferFile; private final String clientHost;
private final LocalBufferFile bufferFile;
private boolean disposed = false; private boolean disposed = false;
private String clientHost;
/** /**
* Construct a remote wrapper for a buffer file. * Construct a remote wrapper for a buffer file.
@ -68,7 +70,6 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
} }
this.clientHost = RepositoryManager.getRMIClient(); this.clientHost = RepositoryManager.getRMIClient();
addInstance(this); addInstance(this);
//System.out.println("Constructed remote buffer file (" + instanceID + "): " + bufferFile);
} }
private static String getFilePathKey(RemoteBufferFileImpl rbf) { private static String getFilePathKey(RemoteBufferFileImpl rbf) {
@ -95,7 +96,6 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
instancePathMap.put(filePathKey, list); instancePathMap.put(filePathKey, list);
} }
list.add(rbf); list.add(rbf);
rbf.owner.fireOpenFileCountChanged();
} }
private static synchronized void removeOwnerInstance(RemoteBufferFileImpl rbf) { private static synchronized void removeOwnerInstance(RemoteBufferFileImpl rbf) {
@ -104,7 +104,6 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
if (list.isEmpty()) { if (list.isEmpty()) {
instanceOwnerMap.remove(rbf.owner); 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 * Get the number of open RemoteBufferFileHandle's associated with the
* specified owner repository handle. * specified owner repository handle.
@ -172,46 +194,26 @@ public class RemoteBufferFileImpl extends UnicastRemoteObject
dispose(); 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. * Dispose associated buffer file and unexport this instance.
*/ */
@Override @Override
public synchronized void dispose() { public void dispose() {
// must handle concurrent invocations
if (!disposed) { removeOwnerInstance(this);
try { removePathInstance(this);
unexportObject(this, true);
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;
} }
} }

View file

@ -39,8 +39,8 @@ import ghidra.util.exception.FileInUseException;
* <code>RepositoryHandleImpl</code> provides a Repository handle to a * <code>RepositoryHandleImpl</code> provides a Repository handle to a
* remote user. * remote user.
*/ */
public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteRepositoryHandle, public class RepositoryHandleImpl extends UnicastRemoteObject
Unreferenced { implements RemoteRepositoryHandle, Unreferenced {
// private final RepositoryChangeEvent NULL_EVENT = new RepositoryChangeEvent( // private final RepositoryChangeEvent NULL_EVENT = new RepositoryChangeEvent(
// RepositoryChangeEvent.REP_NULL_EVENT, null, null, null, null); // RepositoryChangeEvent.REP_NULL_EVENT, null, null, null, null);
@ -191,8 +191,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
} }
RepositoryChangeEvent openFileCountEvent = RepositoryChangeEvent openFileCountEvent =
new RepositoryChangeEvent(RepositoryChangeEvent.REP_OPEN_HANDLE_COUNT, null, null, new RepositoryChangeEvent(RepositoryChangeEvent.REP_OPEN_HANDLE_COUNT, null, null, null,
null, Integer.toString(RemoteBufferFileImpl.getOpenFileCount(this))); Integer.toString(RemoteBufferFileImpl.getOpenFileCount(this)));
synchronized (eventQueue) { synchronized (eventQueue) {
if (clientActive) { if (clientActive) {
@ -213,31 +213,6 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
dispose(); 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 @Override
public RepositoryChangeEvent[] getEvents() throws IOException { public RepositoryChangeEvent[] getEvents() throws IOException {
synchronized (eventQueue) { synchronized (eventQueue) {
@ -414,16 +389,15 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
if (folder == null) { if (folder == null) {
throw new IOException("Failed to create repository Folder " + parentPath); throw new IOException("Failed to create repository Folder " + parentPath);
} }
LocalManagedBufferFile bf = LocalManagedBufferFile bf = folder.createDatabase(itemName, fileID, bufferSize,
folder.createDatabase(itemName, fileID, bufferSize, contentType, currentUser, contentType, currentUser, projectPath);
projectPath);
return new RemoteManagedBufferFileImpl(bf, this, getPathname(parentPath, itemName)); return new RemoteManagedBufferFileImpl(bf, this, getPathname(parentPath, itemName));
} }
} }
@Override @Override
public RemoteManagedBufferFileImpl openDatabase(String parentPath, String itemName, public RemoteManagedBufferFileImpl openDatabase(String parentPath, String itemName, int version,
int version, int minChangeDataVer) throws IOException { int minChangeDataVer) throws IOException {
synchronized (syncObject) { synchronized (syncObject) {
validate(); validate();
RepositoryFile rf = getFile(parentPath, itemName); RepositoryFile rf = getFile(parentPath, itemName);
@ -481,9 +455,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
validate(); validate();
repository.validateWritePrivilege(currentUser); repository.validateWritePrivilege(currentUser);
checkFolderInUse(oldParentPath, oldFolderName); checkFolderInUse(oldParentPath, oldFolderName);
RepositoryFolder folder = RepositoryFolder folder = repository.getFolder(currentUser,
repository.getFolder(currentUser, oldParentPath + FileSystem.SEPARATOR + oldParentPath + FileSystem.SEPARATOR + oldFolderName, false);
oldFolderName, false);
RepositoryFolder newParent = repository.getFolder(currentUser, newParentPath, true); RepositoryFolder newParent = repository.getFolder(currentUser, newParentPath, true);
if (folder != null) { if (folder != null) {
folder.moveTo(newParent, newFolderName, currentUser); 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 { private void checkFileInUse(String parentPath, String itemName) throws FileInUseException {
String[] openFileUsers = String[] openFileUsers = RemoteBufferFileImpl.getOpenFileUsers(repository.getName(),
RemoteBufferFileImpl.getOpenFileUsers(repository.getName(), getPathname(parentPath, itemName));
getPathname(parentPath, itemName));
if (openFileUsers != null) { if (openFileUsers != null) {
StringBuffer buf = new StringBuffer(""); StringBuffer buf = new StringBuffer("");
for (String user : openFileUsers) { for (String user : openFileUsers) {
@ -553,9 +525,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
if (rf.hasCheckouts()) { if (rf.hasCheckouts()) {
return true; return true;
} }
String[] openFileUsers = String[] openFileUsers = RemoteBufferFileImpl.getOpenFileUsers(repository.getName(),
RemoteBufferFileImpl.getOpenFileUsers(repository.getName(), getPathname(folder.getPathname(), rf.getName()));
getPathname(folder.getPathname(), rf.getName()));
if (openFileUsers != null) { if (openFileUsers != null) {
return true; return true;
} }
@ -622,7 +593,8 @@ public class RepositoryHandleImpl extends UnicastRemoteObject implements RemoteR
} }
@Override @Override
public ItemCheckoutStatus[] getCheckouts(String parentPath, String itemName) throws IOException { public ItemCheckoutStatus[] getCheckouts(String parentPath, String itemName)
throws IOException {
synchronized (syncObject) { synchronized (syncObject) {
validate(); validate();
RepositoryFile rf = getFile(parentPath, itemName); RepositoryFile rf = getFile(parentPath, itemName);