Bug 787519 - Make message manager throw when there's no target to send asynchronous message to r=jlebar

This commit is contained in:
Patrick Wang 2012-09-19 19:08:36 +08:00
parent 68e34da122
commit 3cc77910cf
4 changed files with 28 additions and 16 deletions

View File

@ -222,6 +222,13 @@ interface nsIMessageSender : nsIMessageListenerManager
*
* See nsIMessageListener::receiveMessage() for the format of the
* data delivered to listeners.
* @throws NS_ERROR_NOT_INITIALIZED if the sender is not initialized. For
* example, we will throw NS_ERROR_NOT_INITIALIZED if we try to send
* a message to a cross-process frame but the other process has not
* yet been set up.
* @throws NS_ERROR_FAILURE when the message receiver cannot be found. For
* example, we will throw NS_ERROR_FAILURE if we try to send a message
* to a cross-process frame whose process has crashed.
*/
[implicit_jscontext, optional_argc]
void sendAsyncMessage([optional] in AString messageName,

View File

@ -2244,11 +2244,16 @@ bool SendAsyncMessageToChild(void* aCallbackData,
return tabParent->SendAsyncMessage(nsString(aMessage), data);
}
nsRefPtr<nsIRunnable> ev =
new nsAsyncMessageToChild(static_cast<nsFrameLoader*>(aCallbackData),
aMessage, aData);
NS_DispatchToCurrentThread(ev);
return true;
if (static_cast<nsFrameLoader*>(aCallbackData)->mChildMessageManager) {
nsRefPtr<nsIRunnable> ev =
new nsAsyncMessageToChild(static_cast<nsFrameLoader*>(aCallbackData),
aMessage, aData);
NS_DispatchToCurrentThread(ev);
return true;
}
// We don't have any targets to send our asynchronous message to.
return false;
}
NS_IMETHODIMP

View File

@ -287,7 +287,10 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
{
if (mAsyncCallback) {
NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
mAsyncCallback(mCallbackData, aMessage, aData);
if (!mAsyncCallback(mCallbackData, aMessage, aData)) {
return NS_ERROR_FAILURE;
}
}
if (aBroadcast == BROADCAST) {
int32_t len = mChildManagers.Count();

View File

@ -322,15 +322,9 @@ BrowserElementParent.prototype = {
try {
this._mm.sendAsyncMessage('browser-element-api:' + msg, data);
} catch (e) {
// Ignore NS_ERROR_NOT_INITIALIZED. This exception is thrown when
// we call _sendAsyncMsg if our frame is not in the DOM, in which case
// we don't have child to receive the message.
if (e.result == Cr.NS_ERROR_NOT_INITIALIZED) {
debug("Handle NS_ERROR_NOT_INITIALIZED");
return;
}
throw e;
return false;
}
return true;
},
_recvHello: function(data) {
@ -462,8 +456,11 @@ BrowserElementParent.prototype = {
_sendDOMRequest: function(msgName) {
let id = 'req_' + this._domRequestCounter++;
let req = Services.DOMRequest.createRequest(this._window);
this._pendingDOMRequests[id] = req;
this._sendAsyncMsg(msgName, {id: id});
if (this._sendAsyncMsg(msgName, {id: id})) {
this._pendingDOMRequests[id] = req;
} else {
Services.DOMRequest.fireErrorAsync(req, "fail");
}
return req;
},