Browse files

Bug 675221 addendum to part A - reimplement the recursion check for t…

…he console service so that a poorly-written console listener doesn't cause an infinite repeition, r=bent
  • Loading branch information...
1 parent 8b53960 commit bcbfa26780c67b2796699e014c84ef0e786c86fc @bsmedberg bsmedberg committed Jan 11, 2012
Showing with 34 additions and 3 deletions.
  1. +17 −3 xpcom/base/nsConsoleService.cpp
  2. +17 −0 xpcom/base/nsConsoleService.h
View
20 xpcom/base/nsConsoleService.cpp
@@ -68,6 +68,7 @@ nsConsoleService::nsConsoleService()
: mMessages(nsnull)
, mCurrent(0)
, mFull(false)
+ , mDeliveringMessage(false)
, mLock("nsConsoleService.mLock")
{
// XXX grab this from a pref!
@@ -109,8 +110,9 @@ namespace {
class LogMessageRunnable : public nsRunnable
{
public:
- LogMessageRunnable(nsIConsoleMessage* message) :
- mMessage(message)
+ LogMessageRunnable(nsIConsoleMessage* message, nsConsoleService* service)
+ : mMessage(message)
+ , mService(service)
{ }
void AddListener(nsIConsoleListener* listener) {
@@ -121,15 +123,22 @@ class LogMessageRunnable : public nsRunnable
private:
nsCOMPtr<nsIConsoleMessage> mMessage;
+ nsRefPtr<nsConsoleService> mService;
nsCOMArray<nsIConsoleListener> mListeners;
};
NS_IMETHODIMP
LogMessageRunnable::Run()
{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ mService->SetIsDelivering();
+
for (PRInt32 i = 0; i < mListeners.Count(); ++i)
mListeners[i]->Observe(mMessage);
+ mService->SetDoneDelivering();
+
return NS_OK;
}
@@ -151,7 +160,12 @@ nsConsoleService::LogMessage(nsIConsoleMessage *message)
if (message == nsnull)
return NS_ERROR_INVALID_ARG;
- nsRefPtr<LogMessageRunnable> r = new LogMessageRunnable(message);
+ if (NS_IsMainThread() && mDeliveringMessage) {
+ NS_WARNING("Some console listener threw an error while inside itself. Discarding this message");
+ return NS_ERROR_FAILURE;
+ }
+
+ nsRefPtr<LogMessageRunnable> r = new LogMessageRunnable(message, this);
nsIConsoleMessage *retiredMessage;
NS_ADDREF(message); // early, in case it's same as replaced below.
View
17 xpcom/base/nsConsoleService.h
@@ -60,6 +60,18 @@ class nsConsoleService MOZ_FINAL : public nsIConsoleService
NS_DECL_ISUPPORTS
NS_DECL_NSICONSOLESERVICE
+ void SetIsDelivering() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(!mDeliveringMessage);
+ mDeliveringMessage = true;
+ }
+
+ void SetDoneDelivering() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mDeliveringMessage);
+ mDeliveringMessage = false;
+ }
+
private:
~nsConsoleService();
@@ -75,6 +87,11 @@ class nsConsoleService MOZ_FINAL : public nsIConsoleService
// Is the buffer full? (Has mCurrent wrapped around at least once?)
bool mFull;
+ // Are we currently delivering a console message on the main thread? If
+ // so, we suppress incoming messages on the main thread only, to avoid
+ // infinite repitition.
+ bool mDeliveringMessage;
+
// Listeners to notify whenever a new message is logged.
nsInterfaceHashtable<nsISupportsHashKey, nsIConsoleListener> mListeners;

0 comments on commit bcbfa26

Please sign in to comment.