blob: b8ce9f4079c36528ab9f4ce4267a806d161f5a90 [file] [log] [blame]
package org.eclipse.ui.internal;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.WorkspaceLock;
import org.eclipse.swt.widgets.Display;
public class UIWorkspaceLock extends WorkspaceLock {
protected Display display;
protected Thread ui;
protected Semaphore pendingWork;
protected boolean pendingWorkStarted;
public UIWorkspaceLock(IWorkspace workspace, Display display) throws CoreException {
super(workspace);
this.display = display;
pendingWorkStarted = false;
}
public boolean acquire() throws InterruptedException {
if (isUI()) {
Thread currentOperation = getCurrentOperationThread();
if (currentOperation != null) {
if (display.getSyncThread() == currentOperation && isTreeLocked())
throw new RuntimeException(WorkbenchMessages.getString("UIWorkspaceLock.errorModDuringNotification")); //$NON-NLS-1$
// If a syncExec was executed from the current operation, it
// has already acquired the lock. So, just return true.
if (pendingWork != null && pendingWorkStarted && pendingWork.getOperationThread() == currentOperation) {
if (isTreeLocked())
throw new RuntimeException(WorkbenchMessages.getString("UIWorkspaceLock.errorModDuringNotification")); //$NON-NLS-1$
else
return true; // we are a nested operation
}
}
ui = Thread.currentThread();
doPendingWork();
}
return super.acquire();
}
void addPendingWork(Semaphore work) {
pendingWork = work;
}
/**
* Should always be called from the UI thread.
*/
void doPendingWork() {
if (pendingWork == null)
return;
try {
pendingWorkStarted = true;
pendingWork.getRunnable().run();
} finally {
// only null it after running
Semaphore temp = pendingWork;
// the following lines have to be done in
// that order to avoid concurrency problems
pendingWork = null;
pendingWorkStarted = false;
temp.release();
}
}
void interruptUI() {
display.getThread().interrupt();
}
boolean isCurrentOperation() {
return getCurrentOperationThread() == Thread.currentThread();
}
boolean isUI() {
return (!display.isDisposed()) && (display.getThread() == Thread.currentThread());
}
boolean isUIWaiting() {
return (ui != null) && (Thread.currentThread() != ui);
}
public void release() {
if (isUI())
ui = null;
super.release();
}
}