1 11 package org.eclipse.update.internal.core; 12 13 import java.io.*; 14 import java.net.*; 15 import java.util.*; 16 17 import org.eclipse.core.runtime.*; 18 import org.eclipse.osgi.util.NLS; 19 20 38 public class ConnectionThreadManager { 39 private static final String CONNECT_TIMEOUT = "60000"; private static final String READ_TIMEOUT = "60000"; private static final int MAX_COUNT = 9; 45 private Vector threads; 46 47 public static class StreamRunnable implements Runnable { 48 private URLConnection urlConnection; 49 private Exception exception; 50 private InputStream is; 51 private boolean disconnected; 52 53 public StreamRunnable(URLConnection urlConnection) { 54 this.urlConnection = urlConnection; 55 } 56 57 public InputStream getInputStream() { 58 return is; 59 } 60 61 public URL getURL() { 62 return urlConnection.getURL(); 63 } 64 65 public Exception getException() { 66 return exception; 67 } 68 69 public void disconnect() { 70 if (urlConnection instanceof HttpURLConnection) 71 ((HttpURLConnection)urlConnection).disconnect(); 72 disconnected = true; 73 } 74 75 public void run() { 76 try { 77 is = urlConnection.getInputStream(); 78 if (disconnected) { 79 if (is != null) { 85 try { 86 is.close(); 87 } catch (IOException ex) { 88 } finally { 90 is = null; 91 } 92 } 93 } 94 } catch (Exception e) { 95 exception = e; 96 } 97 } 98 } 99 100 class ConnectionThread extends Thread { 101 private StreamRunnable runnable; 102 public ConnectionThread(StreamRunnable runnable) { 103 super(runnable, "update-connection"); this.runnable = runnable; 105 } 106 107 public StreamRunnable getRunnable() { 108 return runnable; 109 } 110 } 111 112 public ConnectionThreadManager() { 113 setIfNotDefaultProperty("sun.net.client.defaultConnectTimeout", CONNECT_TIMEOUT); setIfNotDefaultProperty("sun.net.client.defaultReadTimeout", READ_TIMEOUT); } 117 118 private void setIfNotDefaultProperty(String key, String value) { 119 String oldValue = System.getProperty(key); 120 if (oldValue==null || oldValue.equals("-1")) System.setProperty(key, value); 122 } 123 124 public Thread createThread(StreamRunnable runnable) throws CoreException { 125 validateExistingThreads(); 126 if (threads == null) 127 threads = new Vector(); 128 Thread t = new ConnectionThread(runnable); 129 t.setDaemon(true); 130 threads.add(t); 131 return t; 132 } 133 134 139 private void validateExistingThreads() throws CoreException { 140 if (threads == null) 141 return; 142 143 int aliveCount = purgeTerminatedThreads(); 144 145 if (aliveCount > MAX_COUNT) { 146 ArrayList children = new ArrayList(); 147 String pluginId = 148 UpdateCore.getPlugin().getBundle().getSymbolicName(); 149 for (int i = 0; i < threads.size(); i++) { 150 ConnectionThread t = (ConnectionThread) threads.get(i); 151 String url = t.getRunnable().getURL().toString(); 152 IStatus status = 153 new Status( 154 IStatus.ERROR, 155 pluginId, 156 IStatus.OK, 157 NLS.bind(Messages.ConnectionThreadManager_unresponsiveURL, (new String [] { url })), 158 null); 159 children.add(status); 160 } 161 MultiStatus parentStatus = 162 new MultiStatus( 163 pluginId, 164 IStatus.OK, 165 (IStatus[]) children.toArray(new IStatus[children.size()]), 166 Messages.ConnectionThreadManager_tooManyConnections, 167 null); 168 throw new CoreException(parentStatus); 169 } 170 } 171 172 176 177 private int purgeTerminatedThreads() { 178 int aliveCount = 0; 179 180 Object [] array = threads.toArray(); 181 for (int i = 0; i < array.length; i++) { 182 Thread t = (Thread ) array[i]; 183 if (!t.isAlive()) 184 threads.remove(t); 185 else 186 aliveCount++; 187 } 188 return aliveCount; 189 } 190 191 public void shutdown() { 192 threads.clear(); 196 } 197 } 198 | Popular Tags |