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);
                }
        }



Reply via email to