--- java/org/directwebremoting/engine.js	2007-04-18 07:30:46.000000000 -0700
+++ /tmp/java/org/directwebremoting/engine.js	2007-04-26 16:56:38.000000000 -0700
@@ -38,12 +38,20 @@
 };
 
 /**
+ * Set an alternative error handler for the reverse AJAX errors.
+ * @see getahead.org/dwr/browser/engine/errors
+ */
+dwr.engine.setReverseAjaxErrorHandler = function(handler) {
+  dwr.engine._pollErrorHandler = handler;
+};
+
+/**
  * Setter for the text/html handler - what happens if a DWR request gets an HTML
  * reply rather than the expected Javascript. Often due to login timeout
  */
 dwr.engine.setTextHtmlHandler = function(handler) {
   dwr.engine._textHtmlHandler = handler;
-}
+};
 
 /**
  * Set a default timeout value for all calls. 0 (the default) turns timeouts off.
@@ -144,12 +152,15 @@
     // Bail if we are already started
     if (dwr.engine._activeReverseAjax) return;
     dwr.engine._activeReverseAjax = true;
+    dwr.engine._pollRetries = 0;
     dwr.engine._poll();
   }
   else {
+    // To ignore errors, which may occur during cleanup, indicate that the 
+    // reverse AJAX is disabled.
+    dwr.engine._activeReverseAjax = false;
     // Can we cancel an existing request?
     if (dwr.engine._activeReverseAjax && dwr.engine._pollReq) dwr.engine._pollReq.abort();
-    dwr.engine._activeReverseAjax = false;
   }
   // TODO: in iframe mode, if we start, stop, start then the second start may
   // well kick off a second iframe while the first is still about to return
@@ -190,6 +201,16 @@
   dwr.engine._debug(message);
 };
 
+/** 
+ * The default reverse AJAX error handler.
+ * @see getahead.org/dwr/browser/engine/errors
+ */
+dwr.engine.defaultPollErrorHandler = function(message, ex, retryNum) {
+  // if anything goes wrong then just silently try again (up to 3x) after 10s
+  return retryNum < 3 ? 10000 : -1;
+};
+
+
 /**
  * For reduced latency you can group several remote calls together using a batch.
  * @see getahead.org/dwr/browser/engine/batch
@@ -268,6 +289,9 @@
 /** For debugging when something unexplained happens. */
 dwr.engine._warningHandler = dwr.engine.defaultWarningHandler;
 
+/** A function to call if reverse AJAX fails. */
+dwr.engine._pollErrorHandler = dwr.engine.defaultPollErrorHandler;
+
 /** A function to be called before requests are marshalled. Can be null. */
 dwr.engine._preHook = null;
 
@@ -325,7 +349,6 @@
 
 /** How many times have we re-tried to poll? */
 dwr.engine._pollRetries = 0;
-dwr.engine._maxPollRetries = 0;
 
 /** Do we do a document.reload if we get a text/html reply? */
 dwr.engine._textHtmlHandler = null;
@@ -439,8 +462,8 @@
   batch.path = (overridePath) ? overridePath : dwr.engine._defaultPath;
   batch.preHooks = [];
   batch.postHooks = [];
-  batch.errorHandler = dwr.engine._pollErrorHandler;
-  batch.warningHandler = dwr.engine._pollErrorHandler;
+  batch.errorHandler = dwr.engine._internalPollErrorHandler;
+  batch.warningHandler = dwr.engine._internalPollErrorHandler;
   batch.handlers[0] = {
     callback:function(pause) {
       dwr.engine._pollRetries = 0;
@@ -456,16 +479,19 @@
   }
 };
 
-/** Try to recover from polling errors */
-dwr.engine._pollErrorHandler = function(msg, ex) {
-  // if anything goes wrong then just silently try again (up to 3x) after 10s
-  dwr.engine._pollRetries++;
-  dwr.engine._debug("Reverse Ajax poll failed (pollRetries=" + dwr.engine._pollRetries + "): " + ex.name + " : " + ex.message);
-  if (dwr.engine._pollRetries < dwr.engine._maxPollRetries) {
-    setTimeout("dwr.engine._poll()", 10000);
-  }
-  else {
-    dwr.engine._debug("Giving up.");
+/** @private Try to recover from polling errors */
+dwr.engine._internalPollErrorHandler = function(msg, ex) {
+  if (dwr.engine._activeReverseAjax) {
+    dwr.engine._debug("Reverse Ajax poll failed (pollRetries=" + dwr.engine._pollRetries + "): " + ex.name + " : " + ex.message);
+    var pause = dwr.engine._pollErrorHandler (msg, ex, dwr.engine._pollRetries);
+    dwr.engine._pollRetries++;
+    if (pause >= 0) {
+      setTimeout("dwr.engine._poll()", pause);
+    }
+    else {
+      dwr.engine._debug("Giving up.");
+      dwr.engine.setActiveReverseAjax (false);
+    }
   }
 };
 
@@ -537,7 +563,8 @@
     var cookie = cookies[i];
     while (cookie.charAt(0) == ' ') cookie = cookie.substring(1, cookie.length);
     if (cookie.indexOf(dwr.engine._sessionCookieName + "=") == 0) {
-      return cookie.substring(11, cookie.length);
+      return cookie.substring(dwr.engine._sessionCookieName.length + 1, 
+                              cookie.length);
     }
   }
   return "";

