[freenet-cvs] r15047 - in trunk/freenet/src/freenet: clients/http node pluginmanager

toad at freenetproject.org toad at freenetproject.org
Sat Sep 8 15:49:54 UTC 2007


Author: toad
Date: 2007-09-08 15:49:53 +0000 (Sat, 08 Sep 2007)
New Revision: 15047

Modified:
   trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
   trunk/freenet/src/freenet/node/TextModeClientInterface.java
   trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
   trunk/freenet/src/freenet/pluginmanager/PluginManager.java
Log:
Wait up to a limited time for threaded plugins to finish exiting.

Modified: trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PproxyToadlet.java	2007-09-08 15:37:49 UTC (rev 15046)
+++ trunk/freenet/src/freenet/clients/http/PproxyToadlet.java	2007-09-08 15:49:53 UTC (rev 15047)
@@ -23,6 +23,8 @@
 
 public class PproxyToadlet extends Toadlet {
 	private static final int MAX_PLUGIN_NAME_LENGTH = 1024;
+	/** Maximum time to wait for a threaded plugin to exit */
+	private static final int MAX_THREADED_UNLOAD_WAIT_TIME = 60*1000;
 	private final Node node;
 	private final NodeClientCore core;
 
@@ -124,7 +126,7 @@
 				ctx.sendReplyHeaders(302, "Found", headers, null, 0);
 				return;
 			}if (request.getPartAsString("unloadconfirm", MAX_PLUGIN_NAME_LENGTH).length() > 0) {
-				pm.killPlugin(request.getPartAsString("unloadconfirm", MAX_PLUGIN_NAME_LENGTH));
+				pm.killPlugin(request.getPartAsString("unloadconfirm", MAX_PLUGIN_NAME_LENGTH), MAX_THREADED_UNLOAD_WAIT_TIME);
 				HTMLNode pageNode = ctx.getPageMaker().getPageNode(l10n("plugins"), ctx);
 				HTMLNode contentNode = ctx.getPageMaker().getContentNode(pageNode);
 				HTMLNode infobox = contentNode.addChild("div", "class", "infobox infobox-success");
@@ -164,7 +166,7 @@
 					sendErrorPage(ctx, 404, l10n("pluginNotFoundReloadTitle"), 
 							L10n.getString("PluginToadlet.pluginNotFoundReload"));
 				} else {
-					pm.killPlugin(request.getPartAsString("reload", MAX_PLUGIN_NAME_LENGTH));
+					pm.killPlugin(request.getPartAsString("reload", MAX_PLUGIN_NAME_LENGTH), MAX_THREADED_UNLOAD_WAIT_TIME);
 					pm.startPlugin(fn, true);
 
 					headers.put("Location", ".");

Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java	2007-09-08 15:37:49 UTC (rev 15046)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java	2007-09-08 15:49:53 UTC (rev 15047)
@@ -898,7 +898,7 @@
         } else if(uline.startsWith("PLUGLIST")) {
         	outsb.append(n.pluginManager.dumpPlugins());
         } else if(uline.startsWith("PLUGKILL:")) {
-        	n.pluginManager.killPlugin(line.substring("PLUGKILL:".length()).trim());
+        	n.pluginManager.killPlugin(line.substring("PLUGKILL:".length()).trim(), 60*1000);
         } else {
         	if(uline.length() > 0)
         		printHeader(out);

Modified: trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java	2007-09-08 15:37:49 UTC (rev 15046)
+++ trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java	2007-09-08 15:49:53 UTC (rev 15047)
@@ -3,6 +3,7 @@
 import java.util.Date;
 import java.util.HashSet;
 
+import freenet.support.Logger;
 import freenet.support.StringArray;
 
 public class PluginInfoWrapper {
@@ -20,6 +21,7 @@
 	private boolean isPortForwardPlugin;
 	private String filename;
 	private HashSet toadletLinks=new HashSet(); 
+	private boolean isExiting = false;
 	//public String 
 	
 	public PluginInfoWrapper(FredPlugin plug, String filename) {
@@ -86,12 +88,28 @@
 	 * might be sleeping. Then call removePlugin() on it on the manager - either
 	 * now, if it's threadless, or after it terminates, if it's thread based.
 	 * @param manager The plugin manager object.
+	 * @param maxWaitTime If a plugin is thread-based, we can wait for it to
+	 * terminate. Set to -1 if you don't want to wait at all, 0 to wait forever
+	 * or else a value in milliseconds.
 	 **/
-	public void stopPlugin(PluginManager manager) {
+	public void stopPlugin(PluginManager manager, int maxWaitTime) {
 		plug.terminate();
 		if(thread != null) {
 			thread.interrupt();
 			// Will be removed when the thread exits.
+			if(maxWaitTime >= 0) {
+				try {
+					thread.join(maxWaitTime);
+				} catch (InterruptedException e) {
+					Logger.normal(this, "stopPlugin interrupted while join()ed to terminating plugin thread - maybe one plugin stopping another???");
+				}
+				if(thread.isAlive()) {
+					String error = "Waited for "+thread+" for "+plug+" to exit for "+maxWaitTime+"ms, and it is still alive!";
+					Logger.error(this, error);
+					System.err.println(error);
+					// Dump the thread? Would require post-1.4 features...
+				}
+			}
 		} else {
 			// Remove immediately
 			manager.removePlugin(this);

Modified: trunk/freenet/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginManager.java	2007-09-08 15:37:49 UTC (rev 15046)
+++ trunk/freenet/src/freenet/pluginmanager/PluginManager.java	2007-09-08 15:49:53 UTC (rev 15047)
@@ -280,7 +280,7 @@
 		throw new NotFoundPluginHTTPException("Plugin not found!", "/plugins");
 	}
 
-	public void killPlugin(String name) {
+	public void killPlugin(String name, int maxWaitTime) {
 		PluginInfoWrapper pi = null;
 		boolean found = false;
 		synchronized (pluginWrappers) {
@@ -291,7 +291,7 @@
 			}
 		}
 		if (found) {
-			pi.stopPlugin(this);
+			pi.stopPlugin(this, maxWaitTime);
 		}
 	}
 




More information about the cvs mailing list