diff options
Diffstat (limited to 'plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java')
-rw-r--r-- | plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java | 476 |
1 files changed, 0 insertions, 476 deletions
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java deleted file mode 100644 index db1e31ed3..000000000 --- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMProxyFactoryRegistry.java +++ /dev/null @@ -1,476 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2001, 2005 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.jem.internal.proxy.remote; -/* - - - */ - - -import java.io.IOException; -import java.net.Socket; -import java.text.MessageFormat; -import java.util.Iterator; -import java.util.Stack; - -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.IJobManager; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.*; -import org.eclipse.debug.core.model.IProcess; -import org.eclipse.debug.core.model.IStreamsProxy; - -import org.eclipse.jem.internal.proxy.core.*; -/** - * This is the factory registry to use for Remote VM. - * It adds to the standard registry, connection specific information. - * - * This will always hold onto one connection open until termination is requested. - * That way while the IDE is up, the remove vm won't time out. - */ - -public class REMProxyFactoryRegistry extends BaseProxyFactoryRegistry { - - public static final String REMOTE_REGISTRY_TYPE_ID = "org.eclipse.jem.REMOTE"; //$NON-NLS-1$ - - protected int fServerPort = 0; // The server port to use when making connections. - protected REMCallbackRegistry fCallbackServer; // The callback server thread for this remote vm. - protected Stack fConnectionPool = new Stack(); // Stack of free connections. - protected static int NUMBER_FREE_CONNECTIONS = 5; // Number of free connections to keep open. - protected IProcess fProcess; // The process that is the server. If null and fServerPort is not zero, - // then this registry is in test mode - // and the server is in same the process. - protected String fName; - protected int fCallbackServerPort; - protected Integer fRegistryKey; - protected REMRegistryController fRegistryController; - - protected final static Object TERMINATE_JOB_FAMILY = new Object(); - - // Package protected because only the ProxyVMStarter should set this flag. It would set it if - // working with a debugger because we don't how long it will be to respond to requests when - // someone is working with a debugger. - boolean fNoTimeouts = false; - - // This is set via the static setGlobalNoTimeouts() method, or via debug options flag. It is here so that - // when debugging callbacks, but not debugging remote vm, that no timeouts for any registry will occur. - // Or it can be set through the debug .options flag. - static boolean fGlobalNoTimeouts = "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName()+ProxyRemoteUtil.NO_TIMEOUTS)); //$NON-NLS-1$; - - /** - * Typicall set through the "expression" evaluation of the debugger. - * @param noTimeouts - * - * @since 1.0.0 - */ - public static void setGlobalNoTimeouts(boolean noTimeouts) { - fGlobalNoTimeouts = noTimeouts; - } - - // An internal thread that locks and waits for the remote vm to register itself. - private WaitForRegistrationThread waitRegistrationThread; - - private class WaitForRegistrationThread extends Thread { - public WaitForRegistrationThread() { - super("Wait for remote vm registration thread"); //$NON-NLS-1$ - } - - /** - * @see java.lang.Thread#run() - */ - public void run() { - // Wait for registration. Put it into a thread so this - // can occur while other stuff goes on. It locks the fConnectionPool - // until done so that the first request for a connection by anyone - // else will wait until this thread is finished. - - synchronized(fConnectionPool) { - synchronized(REMProxyFactoryRegistry.this) { - // Notify the main thread that we have the - // connection pool locked. - REMProxyFactoryRegistry.this.notifyAll(); - } - synchronized (this) { - // sync on self so that it can be notified when finally receive the registration - long stopTime = System.currentTimeMillis()+60000; - while (waitRegistrationThread != null && (fNoTimeouts || System.currentTimeMillis() < stopTime)) { - try { - Thread.currentThread().wait(60000); - } catch (InterruptedException e) { - } - } - } - } - - waitRegistrationThread = null; // No longer exists. - } - } - - - public REMProxyFactoryRegistry(REMRegistryController registryController, String name) { - super(REMOTE_REGISTRY_TYPE_ID); - fRegistryController = registryController; - fRegistryKey = fRegistryController.registerRegistry(this); // Register the registry with the plugin. - fName = name; - - // Get the waitRegistrationThread started before we actually launch remote vm so - // that it is waiting when the callback comes in. - synchronized (this) { - waitRegistrationThread = new WaitForRegistrationThread(); - waitRegistrationThread.start(); - - // Now we will wait until the registration callback has been done. The thread will - // signal us when that is done. This is so that we don't continue on and let - // a work connection be requested before we even got a chance to start waiting - // for the registration. - while(true) { - try { - wait(); - break; - } catch (InterruptedException e) { - } - }; - } - } - - public Integer getRegistryKey() { - return fRegistryKey; - } - - public void initializeRegistry(IProcess process) { - fProcess = process; - processListener = new IDebugEventSetListener() { - /** - * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(DebugEvent[]) - */ - public void handleDebugEvents(DebugEvent[] events) { - for (int i = 0; i < events.length; i++) { - DebugEvent e = events[i]; - if (e.getSource() == fProcess && e.getKind() == DebugEvent.TERMINATE) { - // We terminating too soon. Pop up a msg. - IStreamsProxy stProxy = fProcess.getStreamsProxy(); - java.io.StringWriter s = new java.io.StringWriter(); - java.io.PrintWriter w = new java.io.PrintWriter(s); - - String msg = MessageFormat.format(ProxyRemoteMessages.Proxy_Terminated_too_soon_ERROR_, new Object[] {fName}); - w.println(msg); - w.println(ProxyRemoteMessages.VM_TERMINATED_INFO_); - w.println(ProxyRemoteMessages.VM_COMMAND_LINE); - w.println(fProcess.getAttribute(IProcess.ATTR_CMDLINE)); - w.println(ProxyRemoteMessages.VM_TERMINATED_LINE1); - w.println(stProxy.getErrorStreamMonitor().getContents()); - w.println(ProxyRemoteMessages.VM_TERMINATED_LINE2); - w.println(stProxy.getOutputStreamMonitor().getContents()); - w.println(ProxyRemoteMessages.VM_TERMINATED_LINE3); - w.close(); - - DebugModeHelper dh = new DebugModeHelper(); - dh.displayErrorMessage(ProxyRemoteMessages.Proxy_Error_Title, msg); - ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, s.toString(), null)); - processListener = null; - DebugPlugin.getDefault().removeDebugEventListener(this); - terminateRegistry(); - break; - } - } - } - }; - - DebugPlugin.getDefault().addDebugEventListener(processListener); - } - - private IDebugEventSetListener processListener = null; - - /** - * Get the CallbackRegistry - */ - public ICallbackRegistry getCallbackRegistry() { - if (fCallbackServer == null) - fCallbackServer = new REMCallbackRegistry(fName, this); - return fCallbackServer; - } - - /** - * This is called by the registry controller to tell - * the registry to terminate with prejudice all - * pending TerminateJobs. - * - * - * @since 1.1.0 - */ - public static void cancelAllTerminateJobs() { - IJobManager jobManager = Job.getJobManager(); - jobManager.cancel(TERMINATE_JOB_FAMILY); - try { - jobManager.join(TERMINATE_JOB_FAMILY, null); - } catch (OperationCanceledException e) { - } catch (InterruptedException e) { - } - } - - private static class TerminateProcess extends Job { - private IProcess process; - - public TerminateProcess(IProcess process) { - super(ProxyRemoteMessages.REMProxyFactoryRegistry_Job_TerminateProcess_Title); - this.process = process; - } - - public boolean belongsTo(Object family) { - return family == TERMINATE_JOB_FAMILY || super.belongsTo(family); - } - - - /* (non-Javadoc) - * @see java.lang.Thread#run() - */ - public IStatus run(IProgressMonitor mon) { - try { - // There is no join on a process available, so we will have to - // busy wait. Give it 10 seconds in 1/10 second intervals. - for (int i=0; !process.isTerminated() && i<100; i++) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } - } - if (!process.isTerminated()) { - process.terminate(); - } - } catch (DebugException e) { - } - return Status.OK_STATUS; - } - } - - protected void registryTerminated(boolean wait) { - if (processListener != null) { - // Remove listener cause we are now going to terminate process and don't want premature terminate notice. - // Sometimes in shutdown we are called and the debug plugin may of already been shutdown. In that case the db - // will be null and there is nothing remove listener from. - DebugPlugin db = DebugPlugin.getDefault(); - if (db != null) - db.removeDebugEventListener(processListener); - processListener = null; - } - - Job tjob = null; - if (waitRegistrationThread != null) { - synchronized (waitRegistrationThread) { - // Still waiting. close it out. - WaitForRegistrationThread wThread = waitRegistrationThread; - waitRegistrationThread = null; - wThread.notifyAll(); - } - } - if (fServerPort != 0) { - IREMConnection closeCon = null; // The connection we will use to close the remote vm. - synchronized(fConnectionPool) { - // Now we walk through all of the free connections and close them properly. - Iterator itr = fConnectionPool.iterator(); - if (itr.hasNext()) - closeCon = (IREMConnection) itr.next(); - while (itr.hasNext()) { - IREMConnection con = (IREMConnection) itr.next(); - con.close(); - } - } - - // Now we terminate the server. - if (closeCon == null) - try { - closeCon = getFreeConnection(); // There weren't any free connections, so get a new one so that we can close it. - } catch (IllegalStateException e) { - // Do nothing, don't want to stop termination just because we can't get a connection. - } - if (closeCon != null) { - closeCon.terminateServer(); // We got a connection to terminate (process may of terminated early, so we would not have a conn then). - } - fConnectionPool.clear(); - fServerPort = 0; - - if (fProcess != null && !fRegistryController.inShutDown()) { - tjob = new TerminateProcess(fProcess); - tjob.setSystem(true); - tjob.schedule(); - fProcess = null; - } - } - - if (fCallbackServer != null) { - fCallbackServer.requestShutdown(); - fCallbackServer = null; - } - - fConnectionPool.clear(); - fRegistryController.deregisterRegistry(fRegistryKey); // De-register this registry. - - if (wait && tjob != null) { - try { - tjob.join(); - } catch (InterruptedException e) { - // It timed out, so we'll just go on. - } - } - } - - /** - * Return the server port number. - */ - public int getServerPort() { - return fServerPort; - } - - /* - * set the server port. - */ - void setServerPort(int serverport) { - fServerPort = serverport; - if (waitRegistrationThread != null) { - synchronized (waitRegistrationThread) { - // Close it out, we are now registered - WaitForRegistrationThread wThread = waitRegistrationThread; - waitRegistrationThread = null; - wThread.notifyAll(); - } - } - } - - /** - * Get a free connection - * @return - * @throws IllegalStateException - Thrown if a connection cannot be created. - * - * @since 1.0.0 - */ - public IREMConnection getFreeConnection() throws IllegalStateException { - Thread thread = Thread.currentThread(); - if (thread instanceof REMCallbackThread) { - // The current thread is a call back thread, so just reuse the connection. - // But this thread could actually be trying to access another registry. - // So if this thread is for this registry, use it, if not for this registry, create a new connection. - // But if for this registry AND is already in a transaction, we need a fresh connection. - REMCallbackThread callbackThread = (REMCallbackThread) thread; - if (callbackThread.registry == this && !callbackThread.inTransaction()) { - // This way any calls out to the remote vm will be on same thread as callback caller - // on remote vm because that thread is waiting on this connection for commands. - IREMConnection c = (callbackThread).getConnection(); - if (c.isConnected()) - return c; - else - throw new IllegalStateException(ProxyRemoteMessages.REMProxyFactoryRegistry_CallbackConnectionNotWorking_EXC_); - } - } - synchronized(fConnectionPool) { - if (!fConnectionPool.isEmpty()) - return (IREMConnection) fConnectionPool.pop(); - // else we need to allocate one. - return createConnection(); - } - } - - - /** - * Make a new connection. - * @return - * @throws IllegalStateException - Thrown if connection cannot be created. - * - * @since 1.0.0 - */ - protected IREMConnection createConnection() throws IllegalStateException { - // If we have a server port, then the server is probably open. If we don't then there is no server. - if (fServerPort != 0) { - // We are putting it off into a thread because there are no timeout capabilities on getting a socket. - // So we need to allow for that. - final Socket[] scArray = new Socket[1]; - final boolean[] waiting = new boolean[] {true}; - Thread doIt = new Thread(new Runnable() { - public void run() { - try { - Socket sc = new Socket("localhost", fServerPort); //$NON-NLS-1$ - synchronized (this) { - if (waiting[0]) - scArray[0] = sc; - else - sc.close(); // We are no longer waiting on this thread so close the socket since no one will use it. - } - } catch (IOException e) { - ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$ - } - } - }); - - doIt.start(); - while (true) { - try { - doIt.join(!fNoTimeouts ? 60000 : 0); - synchronized (doIt) { - waiting[0] = false; // To let it know we are no longer waiting - } - break; - } catch (InterruptedException e) { - } - } - - if (scArray[0] == null) { - // Log where we are at so we can know where it was we down. - ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", new IllegalStateException(ProxyRemoteMessages.REMProxyFactoryRegistry_ConnectionCreationFailed_INFO_))); //$NON-NLS-1$ - throw new IllegalStateException(ProxyRemoteMessages.REMProxyFactoryRegistry_CouldNotCreateSocketConnectionToRemoteVM_EXC_); // Couldn't get one, probably server is down. //$NON-NLS-1$ - } - - REMConnection connection = new REMConnection(scArray[0], fNoTimeouts); - if (connection.isConnected()) - return connection; - - // Failed, close the socket. - try { - scArray[0].close(); - } catch (IOException e) { - } - } else - ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "No Server to retrieve a connection.", null)); ///$NON-NLS-1$ - - throw new IllegalStateException(ProxyRemoteMessages.REMProxyFactoryRegistry_CouldNotCreateSocketConnectionToRemoteVM_EXC_); - } - - /** - * Free the connection - */ - public void returnConnection(IREMConnection connection) { - if (connection.isConnected()) { - Thread thread = Thread.currentThread(); - if (!(thread instanceof REMCallbackThread) || ((REMCallbackThread) thread).getConnection() != connection) { - // We are not a callback thread, or we are but the connection is not for the thread, then the connection - // can be returned. - synchronized (fConnectionPool) { - if (fConnectionPool.size() < NUMBER_FREE_CONNECTIONS) - fConnectionPool.push(connection); - else - connection.close(); // We don't need to maintain more than five free connections. - } - } - } - } - - /** - * Release this connection. This means close it out. - */ - public void closeConnection(IREMConnection connection) { - connection.close(); - } - - - public int connectionCount() { - synchronized (fConnectionPool) { - return fConnectionPool.size(); - } - } -} |