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/npapi/LocalObjectTable.h b/plugins/npapi/LocalObjectTable.h
index 7d95509..1fa69c2 100644
--- a/plugins/npapi/LocalObjectTable.h
+++ b/plugins/npapi/LocalObjectTable.h
@@ -38,8 +38,7 @@
}
public:
- LocalObjectTable() {
- dontFree = false;
+ LocalObjectTable(): nextId(0), dontFree(false) {
}
virtual ~LocalObjectTable();
@@ -68,11 +67,11 @@
Debug::log(Debug::Error) << "Freeing freed object slot " << id << Debug::flush;
return;
}
- setFree(id);
if (!dontFree) {
NPObject* obj = it->second;
NPN_ReleaseObject(obj);
}
+ setFree(id);
}
void freeAll() {
diff --git a/plugins/npapi/ScriptableInstance.cpp b/plugins/npapi/ScriptableInstance.cpp
index 6149ffc..273fd8a 100644
--- a/plugins/npapi/ScriptableInstance.cpp
+++ b/plugins/npapi/ScriptableInstance.cpp
@@ -63,6 +63,7 @@
connectedID(NPN_GetStringIdentifier("connected")),
statsID(NPN_GetStringIdentifier("stats")),
gwtId(NPN_GetStringIdentifier("__gwt_ObjectId")),
+ jsDisconnectedID(NPN_GetStringIdentifier("__gwt_disconnected")),
jsInvokeID(NPN_GetStringIdentifier("__gwt_jsInvoke")),
jsResultID(NPN_GetStringIdentifier("__gwt_makeResult")),
jsTearOffID(NPN_GetStringIdentifier("__gwt_makeTearOff")),
@@ -542,24 +543,27 @@
for (unsigned i = 0; i < numArgs; ++i) {
vargs[i] = NPVariantProxy::getAsValue(args[i], *this);
}
+ bool isException = false;
+ Value returnValue;
if (!InvokeMessage::send(*_channel, javaThis, dispId, numArgs, vargs.get())) {
Debug::log(Debug::Error) << "JavaObject_invoke: failed to send invoke message" << Debug::flush;
- // TODO(jat): returning false here spams the browser console
- return true;
- }
- Debug::log(Debug::Debugging) << " return from invoke" << Debug::flush;
- scoped_ptr<ReturnMessage> retMsg(_channel->reactToMessagesWhileWaitingForReturn(this));
- if (!retMsg.get()) {
- Debug::log(Debug::Error) << "JavaObject_invoke: failed to get return value" << Debug::flush;
- return false;
- }
- if (isRawToString) {
- // toString() needs the raw value
- NPVariantProxy::assignFrom(*this, *result, retMsg->getReturnValue());
- return !retMsg->isException();
+ } else {
+ Debug::log(Debug::Debugging) << " return from invoke" << Debug::flush;
+ scoped_ptr<ReturnMessage> retMsg(_channel->reactToMessagesWhileWaitingForReturn(this));
+ if (!retMsg.get()) {
+ Debug::log(Debug::Error) << "JavaObject_invoke: failed to get return value" << Debug::flush;
+ } else {
+ if (isRawToString) {
+ // toString() needs the raw value
+ NPVariantProxy::assignFrom(*this, *result, retMsg->getReturnValue());
+ return !retMsg->isException();
+ }
+ isException = retMsg->isException();
+ returnValue = retMsg->getReturnValue();
+ }
}
// Wrap the result
- return makeResult(retMsg->isException(), retMsg->getReturnValue(), result);
+ return makeResult(isException, returnValue, result);
}
bool ScriptableInstance::JavaObject_getProperty(int objectId, int dispId,
@@ -651,6 +655,11 @@
javaObjectsToFree.insert(objectId);
}
+void ScriptableInstance::disconnectDetectedImpl() {
+ NPVariantWrapper result(*this);
+ NPN_Invoke(getNPP(), window, jsDisconnectedID, 0, 0, result.addressForReturn());
+}
+
void ScriptableInstance::sendFreeValues(HostChannel& channel) {
unsigned n = javaObjectsToFree.size();
if (n) {
diff --git a/plugins/npapi/ScriptableInstance.h b/plugins/npapi/ScriptableInstance.h
index cdce6f3..2d03a67 100644
--- a/plugins/npapi/ScriptableInstance.h
+++ b/plugins/npapi/ScriptableInstance.h
@@ -72,6 +72,10 @@
void destroyJavaWrapper(JavaObject*);
static const uint32_t VERSION = 1;
+
+protected:
+ virtual void disconnectDetectedImpl();
+
private:
// Map of object ID to JavaObject
hash_map<int, JavaObject*> javaObjects;
@@ -94,6 +98,7 @@
const NPIdentifier statsID;
const NPIdentifier gwtId;
+ const NPIdentifier jsDisconnectedID;
const NPIdentifier jsInvokeID;
const NPIdentifier jsResultID;
const NPIdentifier jsTearOffID;