blob: 5c9a08113ddeb2d60e4079bd3236c65ea79fa37e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.ui.tests.concurrency;
import org.eclipse.swt.widgets.Display;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import junit.framework.TestCase;
/**
* This tests the simple traditional deadlock of a thread holding a lock trying
* to perform a syncExec, while the UI thread is waiting for that lock.
* UISynchronizer and UILockListener conspire to prevent deadlock in this case.
*/
public class SyncExecWhileUIThreadWaitsForLock extends TestCase {
public void testDeadlock() {
final ILock lock = Job.getJobManager().newLock();
final boolean[] blocked = new boolean[] {false};
final boolean[] lockAcquired= new boolean[] {false};
Thread locking = new Thread("SyncExecWhileUIThreadWaitsForLock") {
public void run() {
try {
//first make sure this background thread owns the lock
lock.acquire();
//spawn an asyncExec that will cause the UI thread to be blocked
Display.getDefault().asyncExec(new Runnable() {
public void run() {
blocked[0] = true;
lock.acquire();
lock.release();
blocked[0] = false;
}
});
//wait until the UI thread is blocked waiting for the lock
while (!blocked[0]) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
//now attempt to do a syncExec that also acquires the lock
//this should succeed even while the above asyncExec is blocked, thanks to UISynchronizer
Display.getDefault().syncExec(new Runnable() {
public void run() {
try {
//use a timeout to avoid deadlock in case of regression
if (lock.acquire(60000)) {
//this flag is used to verify that we actually acquired the lock
lockAcquired[0] = true;
lock.release();
}
} catch (InterruptedException e) {
}
}
});
} finally {
lock.release();
}
}
};
locking.start();
//wait until we succeeded to acquire the lock in the UI thread
long waitStart = System.currentTimeMillis();
Display display = Display.getDefault();
while (!lockAcquired[0]) {
//spin event loop so that asyncExed above gets run
if (!display.readAndDispatch())
display.sleep();
//if we waited too long, fail the test
if (System.currentTimeMillis()-waitStart > 60000)
assertTrue("Deadlock occurred", false);
}
//if we get here, the test succeeded
}
}