Bug 675221 addendum to part A - reimplement the recursion check for the console service so that a poorly-written console listener doesn't cause an infinite repeition, r=bent

This commit is contained in:
Benjamin Smedberg 2012-01-11 11:28:21 -05:00
parent 00e37f7b43
commit fce89eafbe
2 changed files with 34 additions and 3 deletions

View File

@ -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 @@ public:
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 File

@ -60,6 +60,18 @@ public:
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 @@ private:
// 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;