IE, Chrome, Firefox plugins: gracefully disconnect when server connection drops.
1) Plugins fails gracefully in the face of a disconnect, returning undefined instead of making lots of noise.
2) Plugins invokes hosted.html's __gwt_disconnected() method the first time the session is detected as dropped. This glasspanels the app.
Review by: jat
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7129 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/xpcom/FFSessionHandler.cpp b/plugins/xpcom/FFSessionHandler.cpp
index a2b5cc4..b7ad7ff 100755
--- a/plugins/xpcom/FFSessionHandler.cpp
+++ b/plugins/xpcom/FFSessionHandler.cpp
@@ -128,6 +128,26 @@
}
}
+void FFSessionHandler::disconnectDetectedImpl() {
+ JSContext* ctx = getJSContext();
+ if (!ctx) {
+ return;
+ }
+
+ Debug::log(Debug::Debugging) << "Getting function \"__gwt_disconnected\""
+ << Debug::flush;
+
+ jsval funcVal;
+ if (!JS_GetProperty(ctx, global, "__gwt_disconnected", &funcVal)
+ || funcVal == JSVAL_VOID) {
+ Debug::log(Debug::Error) << "Could not get function \"__gwt_disconnected\""
+ << Debug::flush;
+ return;
+ }
+ jsval rval;
+ JS_CallFunctionValue(ctx, global, funcVal, 0, 0, &rval);
+}
+
void FFSessionHandler::freeValue(HostChannel& channel, int idCount, const int* ids) {
Debug::DebugStream& dbg = Debug::log(Debug::Spam)
<< "FFSessionHandler::freeValue [ ";
diff --git a/plugins/xpcom/FFSessionHandler.h b/plugins/xpcom/FFSessionHandler.h
index f7fec2b..1da4288 100755
--- a/plugins/xpcom/FFSessionHandler.h
+++ b/plugins/xpcom/FFSessionHandler.h
@@ -41,6 +41,7 @@
void disconnect();
protected:
+ virtual void disconnectDetectedImpl();
virtual void freeValue(HostChannel& channel, int idCount, const int* ids);
virtual void loadJsni(HostChannel& channel, const std::string& js);
virtual bool invoke(HostChannel& channel, const Value& thisObj, const std::string& methodName,
diff --git a/plugins/xpcom/JavaObject.cpp b/plugins/xpcom/JavaObject.cpp
index 638094f..ca0104b 100644
--- a/plugins/xpcom/JavaObject.cpp
+++ b/plugins/xpcom/JavaObject.cpp
@@ -359,17 +359,21 @@
for (int i = 0; i < numArgs; ++i) {
data->makeValueFromJsval(args[i], ctx, jsargs[i]);
}
+
+ bool isException = false;
+ Value returnValue;
if (!InvokeMessage::send(*channel, javaThis, dispId, numArgs, args.get())) {
Debug::log(Debug::Debugging) << "JavaObject::call failed to send invoke message" << Debug::flush;
- return false;
+ } else {
+ Debug::log(Debug::Spam) << " return from invoke" << Debug::flush;
+ scoped_ptr<ReturnMessage> retMsg(channel->reactToMessagesWhileWaitingForReturn(handler));
+ if (!retMsg.get()) {
+ Debug::log(Debug::Debugging) << "JavaObject::call failed to get return value" << Debug::flush;
+ } else {
+ isException = retMsg->isException();
+ returnValue = retMsg->getReturnValue();
+ }
}
- Debug::log(Debug::Spam) << " return from invoke" << Debug::flush;
- scoped_ptr<ReturnMessage> retMsg(channel->reactToMessagesWhileWaitingForReturn(handler));
- if (!retMsg.get()) {
- Debug::log(Debug::Debugging) << "JavaObject::call failed to get return value" << Debug::flush;
- return false;
- }
- Value returnValue = retMsg->getReturnValue();
// Since we can set exceptions normally, we always return false to the
// wrapper function and set the exception ourselves if one occurs.
// TODO: cleanup exception case
@@ -379,7 +383,7 @@
jsval retJsVal;
Debug::log(Debug::Spam) << " result is " << returnValue << Debug::flush;
data->makeJsvalFromValue(retJsVal, ctx, returnValue);
- if (retMsg->isException()) {
+ if (isException) {
JS_SetPendingException(ctx, retJsVal);
return false;
}