blob: 1a61b92fa4ca4c02184864ab2fc5cc9fc3dee335 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.dbgp.internal.commands;
import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.Map;
import org.eclipse.dltk.dbgp.DbgpBaseCommands;
import org.eclipse.dltk.dbgp.DbgpRequest;
import org.eclipse.dltk.dbgp.IDbgpCommunicator;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.dbgp.exceptions.DbgpIOException;
import org.eclipse.dltk.dbgp.exceptions.DbgpOpertionCanceledException;
import org.eclipse.dltk.dbgp.exceptions.DbgpTimeoutException;
import org.eclipse.dltk.dbgp.internal.IDbgpDebugingEngine;
import org.eclipse.dltk.dbgp.internal.packets.DbgpResponsePacket;
import org.eclipse.dltk.dbgp.internal.utils.DbgpXmlParser;
import org.eclipse.dltk.debug.core.DLTKDebugPlugin;
import org.eclipse.dltk.debug.core.DLTKDebugPreferenceConstants;
import org.eclipse.dltk.debug.core.DebugOption;
import org.eclipse.dltk.debug.core.IDebugOptions;
import org.w3c.dom.Element;
public class DbgpDebuggingEngineCommunicator implements IDbgpCommunicator {
private final int timeout;
private final IDbgpDebugingEngine engine;
private IDebugOptions options;
private void sendRequest(DbgpRequest command) throws IOException {
engine.sendCommand(command);
}
private DbgpResponsePacket receiveResponse(int transactionId)
throws IOException, InterruptedException {
return engine.getResponsePacket(transactionId, timeout);
}
public DbgpDebuggingEngineCommunicator(IDbgpDebugingEngine engine,
IDebugOptions options) {
if (engine == null) {
throw new IllegalArgumentException();
}
this.engine = engine;
this.options = options;
timeout = DLTKDebugPlugin.getDefault().getPluginPreferences().getInt(
DLTKDebugPreferenceConstants.PREF_DBGP_RESPONSE_TIMEOUT);
}
private final Map<DbgpRequest, DbgpRequest> activeRequests = new IdentityHashMap<>();
@Override
public Element communicate(DbgpRequest request) throws DbgpException {
try {
final DbgpResponsePacket packet;
final int requestId = Integer
.parseInt(request.getOption(DbgpBaseCommands.ID_OPTION));
if (options.get(DebugOption.DBGP_ASYNC) || request.isAsync()) {
sendRequest(request);
packet = receiveResponse(requestId);
} else {
final long startTime = DEBUG ? System.currentTimeMillis() : 0;
beginSyncRequest(request);
if (DEBUG) {
final long waited = System.currentTimeMillis() - startTime;
if (waited > 0) {
System.out.println("Waited " + waited + " ms"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
try {
sendRequest(request);
packet = receiveResponse(requestId);
} finally {
endSyncRequest(request);
}
}
if (packet == null) {
throw new DbgpTimeoutException();
}
Element response = packet.getContent();
DbgpException e = DbgpXmlParser.checkError(response);
if (e != null) {
throw e;
}
return response;
} catch (InterruptedException e) {
throw new DbgpOpertionCanceledException(e);
} catch (IOException e) {
throw new DbgpIOException(e);
}
}
private void endSyncRequest(DbgpRequest request) {
synchronized (activeRequests) {
activeRequests.remove(request);
activeRequests.notifyAll();
}
}
private void beginSyncRequest(DbgpRequest request)
throws InterruptedException {
synchronized (activeRequests) {
while (!activeRequests.isEmpty()) {
activeRequests.wait();
}
activeRequests.put(request, request);
}
}
@Override
public void send(DbgpRequest request) throws DbgpException {
try {
sendRequest(request);
} catch (IOException e) {
throw new DbgpIOException(e);
}
}
private static final boolean DEBUG = false;
@Override
public IDebugOptions getDebugOptions() {
return options;
}
@Override
public void configure(IDebugOptions debugOptions) {
this.options = debugOptions;
}
}