diff --git a/js/src/xpconnect/src/xpcwrappedjs.cpp b/js/src/xpconnect/src/xpcwrappedjs.cpp index 59bc773215b1..846c25b40ac2 100644 --- a/js/src/xpconnect/src/xpcwrappedjs.cpp +++ b/js/src/xpconnect/src/xpcwrappedjs.cpp @@ -44,6 +44,7 @@ #include "xpcprivate.h" #include "nsAtomicRefcnt.h" #include "nsThreadUtils.h" +#include "nsTextFormatter.h" // NOTE: much of the fancy footwork is done in xpcstubs.cpp @@ -572,6 +573,17 @@ nsXPCWrappedJS::CallMethod(PRUint16 methodIndex, if(!IsValid()) return NS_ERROR_UNEXPECTED; if (NS_IsMainThread() != mMainThread) { + NS_NAMED_LITERAL_STRING(kFmt, "Attempt to use JS function on a different thread calling %s.%s. JS objects may not be shared across threads."); + PRUnichar* msg = + nsTextFormatter::smprintf(kFmt.get(), + GetClass()->GetInterfaceName(), + info->name); + nsCOMPtr cs = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (cs) + cs->LogStringMessage(msg); + NS_Free(msg); + return NS_ERROR_NOT_SAME_THREAD; } return GetClass()->CallMethod(this, methodIndex, info, params); diff --git a/js/src/xpconnect/tests/unit/test_bug608142.js b/js/src/xpconnect/tests/unit/test_bug608142.js index ab1cd93d1206..0aea65e207bf 100644 --- a/js/src/xpconnect/tests/unit/test_bug608142.js +++ b/js/src/xpconnect/tests/unit/test_bug608142.js @@ -40,6 +40,19 @@ function run_test() { var tm = Components.classes["@mozilla.org/thread-manager;1"].getService(); var thr = tm.newThread(0); + var foundThreadError = false; + + var listener = { + observe: function(message) { + if (/JS function on a different thread/.test(message.message)) + foundThreadError = true; + } + }; + + var cs = Components.classes["@mozilla.org/consoleservice;1"]. + getService(Components.interfaces.nsIConsoleService); + cs.registerListener(listener); + thr.dispatch({ run: function() { do_check_true(false); @@ -47,5 +60,8 @@ function run_test() { }, Components.interfaces.nsIThread.DISPATCH_NORMAL); thr.shutdown(); + + cs.unregisterListener(listener); + do_check_true(foundThreadError); }