/** * */ package org.keplerproject.ldt.debug.core.model; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugTarget; /** * @author jasonsantos */ public class LuaDebugServer { String fHost; int fControlPort; int fEventPort; private LuaDebugElement fElement; // sockets to communicate with VM private ServerSocket fRemdebugServer; private Socket fRemdebugSocket; private Socket fRemdebugEventSocket; private PrintWriter fRequestWriter; private BufferedReader fRequestReader; // reader for event data private ServerSocket fEventServer; private BufferedReader fEventReader; private boolean fStarted; private boolean fListening; private final Job fRequestJob = new Job("Remdebug Request Dispatcher") { @Override protected IStatus run(IProgressMonitor monitor) { try { start(); return Status.OK_STATUS; } catch (DebugException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } terminate(); fElement.getLuaDebugTarget().terminated(); return Status.CANCEL_STATUS; } }; private final Job fEventsJob = new Job("Remdebug Event Dispatcher") { @Override protected IStatus run(IProgressMonitor monitor) { LuaDebugTarget target = null; while (!fStarted) Thread.yield(); try { String event = receive(); if (event == null) { terminate(); return Status.CANCEL_STATUS; } // Thread.sleep(1000); target = fElement.getLuaDebugTarget(); while ((target != null && !target.isTerminated()) && event != null) { if (event != null) { for (ILuaEventListener l : target.getEventListeners()) { l.handleEvent(event); } } if (!target.isTerminated()) event = receive(); } } catch (IOException e) { target.terminated(); } catch (DebugException e) { System.out.println("Error receiving event:" + e.getMessage()); target.terminated(); } terminate(); return Status.OK_STATUS; } }; public LuaDebugServer(String host, int controlPort, int eventPort) throws DebugException, IOException { fControlPort = controlPort; fEventPort = eventPort; fHost = host; fRequestJob.setSystem(true); fEventsJob.setSystem(true); fRequestJob.schedule(); } /** * @throws DebugException */ private void start() throws DebugException, IOException { fRemdebugServer = new ServerSocket(fControlPort); fRemdebugServer.setSoTimeout(5000); fRemdebugSocket = fRemdebugServer.accept(); fRemdebugServer.close(); fRequestWriter = new PrintWriter(fRemdebugSocket.getOutputStream()); fRequestReader = new BufferedReader(new InputStreamReader( fRemdebugSocket.getInputStream())); fStarted = true; startListen(); fEventsJob.schedule(); } private synchronized void startListen() throws IOException { if (!fListening) { fEventServer = new ServerSocket(fEventPort); fRemdebugEventSocket = fEventServer.accept(); fListening = true; } } public void register(IDebugTarget target) throws DebugException { try { fElement = new LuaDebugElement(target); /* * TODO create several event ports for multithreading debuggers */ while (!fStarted) Thread.yield(); String result = sendRequest("SUBSCRIBE " + fEventPort); if (!result.startsWith("200")) throw new IOException("Can't connect to event port"); while (!fListening) Thread.yield(); fEventReader = new BufferedReader(new InputStreamReader( fRemdebugEventSocket.getInputStream())); } catch (UnknownHostException e) { fElement.requestFailed("Unable to connect to Remdebug", e); } catch (IOException e) { fElement.requestFailed("Unable to connect to Remdebug", e); } } /* * (non-Javadoc) * * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier() */ public String getModelIdentifier() { return fElement.getDebugTarget().getModelIdentifier(); } public String sendRequest(String request) throws IOException { synchronized (fRemdebugSocket) { System.out.println(">>> " + request); fRequestWriter.println(request); fRequestWriter.flush(); String response = fRequestReader.readLine(); System.out.println("<<< " + response); return response; } } public String receive() throws IOException, DebugException { startListen(); if (fEventReader != null) { String response = fEventReader.readLine(); System.out.println("<-- " + response); return response; } else return "100 Continue"; } public void terminate() { fRequestJob.cancel(); fEventsJob.cancel(); try { fRequestWriter.close(); fRequestReader.close(); fRemdebugSocket.close(); fRemdebugServer.close(); fEventReader.close(); fEventServer.close(); } catch (IOException e) { e.printStackTrace(); } } }