mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
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:
parent
00e37f7b43
commit
fce89eafbe
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user