mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-29 03:45:35 +02:00
[291342] DSF session executor intermittently deadlocks during session termination
This commit is contained in:
parent
ed290e9aad
commit
f0ad66391f
1 changed files with 30 additions and 5 deletions
|
@ -21,6 +21,8 @@ import java.io.PipedOutputStream;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
@ -238,9 +240,26 @@ public class MIInferiorProcess extends Process
|
||||||
return exitValue();
|
return exitValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see java.lang.Process#exitValue()
|
* Thrown by {@link MIInferiorProcess#exitValue()} when it is unable to
|
||||||
*/
|
* determine the exit value.
|
||||||
|
*/
|
||||||
|
public static class ExitValueUnavailableException extends IllegalThreadStateException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ExitValueUnavailableException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will throw an {@link ExitValueUnavailableException} if the DSF session
|
||||||
|
* executor is unavailable (for more than 300ms). We do not wait
|
||||||
|
* indefinitely, as our caller may have a lock that the active
|
||||||
|
* Runnable/Callable is waiting for, and that could cause a deadlock.
|
||||||
|
*
|
||||||
|
* @see java.lang.Process#exitValue()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int exitValue() {
|
public int exitValue() {
|
||||||
if (fExitCode != null) {
|
if (fExitCode != null) {
|
||||||
|
@ -280,13 +299,19 @@ public class MIInferiorProcess extends Process
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fSession.getExecutor().execute(exitCodeQuery);
|
fSession.getExecutor().execute(exitCodeQuery);
|
||||||
fExitCode = exitCodeQuery.get();
|
|
||||||
|
try {
|
||||||
|
// Don't wait indefinitely. See bugzilla 291342
|
||||||
|
fExitCode = exitCodeQuery.get(300, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
exitCodeQuery.cancel(false);
|
||||||
|
throw new ExitValueUnavailableException("Timed out waiting for availability of DSF executor."); //$NON-NLS-1$
|
||||||
|
}
|
||||||
return fExitCode;
|
return fExitCode;
|
||||||
} catch (RejectedExecutionException e) {
|
} catch (RejectedExecutionException e) {
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
} catch (CancellationException e) {
|
} catch (CancellationException e) {
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
// Che
|
|
||||||
if (e.getCause() instanceof CoreException &&
|
if (e.getCause() instanceof CoreException &&
|
||||||
((CoreException)e.getCause()).getStatus().getException() instanceof RuntimeException )
|
((CoreException)e.getCause()).getStatus().getException() instanceof RuntimeException )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue