Bug 965373 - When the profiler stops it doesn't stop the EventTracer thread; r=bgirard

---
 toolkit/xre/EventTracer.cpp   | 48 +++++++++++++++++++++++++++++++------------
 tools/profiler/nsProfiler.cpp |  3 +++
 2 files changed, 38 insertions(+), 13 deletions(-)

--HG--
extra : rebase_source : 249b164d232320bbec25de2b13d23ed87ffff842
This commit is contained in:
Viktor Stanchev 2014-02-06 11:59:25 -05:00
parent b3bae35e9e
commit dc0ed322d5
2 changed files with 38 additions and 13 deletions

View File

@ -58,6 +58,7 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/WidgetTraceEvent.h"
#include "nsDebug.h"
#include "MainThreadUtils.h"
#include <limits.h>
#include <prenv.h>
#include <prinrval.h>
@ -75,13 +76,16 @@ using mozilla::TimeStamp;
using mozilla::FireAndWaitForTracerEvent;
namespace {
struct TracerStartClosure {
mozilla::Atomic<int> mLogTracing;
};
}
PRThread* sTracerThread = nullptr;
bool sExit = false;
struct TracerStartClosure {
bool mLogTracing;
};
static PRThread* sTracerThread = nullptr;
static mozilla::Atomic<int> sExit(0);
static int sStartCount = 0;
static bool sLogging = false;
static TracerStartClosure *sTracerStartClosure = nullptr;
#ifdef MOZ_WIDGET_GONK
class EventLoopLagDispatcher : public nsRunnable
@ -118,7 +122,7 @@ class EventLoopLagDispatcher : public nsRunnable
* settting the environment variable MOZ_INSTRUMENT_EVENT_LOOP_OUTPUT
* to the name of a file to use.
*/
void TracerThread(void *arg)
static void TracerThread(void *arg)
{
PR_SetCurrentThreadName("Event Tracer");
@ -209,29 +213,39 @@ void TracerThread(void *arg)
delete threadArgs;
}
} // namespace
namespace mozilla {
bool InitEventTracing(bool aLog)
{
if (sTracerThread)
MOZ_ASSERT(NS_IsMainThread());
// Keep track of how many times we were started and wait for everyone
// who needs us to tell us to shut down before we shut down
sStartCount++;
// If the tracer is already on we just make sure that the logging
// setting is on (if anyone asked for it)
if (sTracerThread) {
if (aLog)
sTracerStartClosure->mLogTracing = 1;
return true;
}
// Initialize the widget backend.
if (!InitWidgetTracing())
return false;
// The tracer thread owns the object and will delete it.
TracerStartClosure* args = new TracerStartClosure();
args->mLogTracing = aLog;
sTracerStartClosure = new TracerStartClosure();
sTracerStartClosure->mLogTracing = aLog;
// Create a thread that will fire events back at the
// main thread to measure responsiveness.
NS_ABORT_IF_FALSE(!sTracerThread, "Event tracing already initialized!");
sTracerThread = PR_CreateThread(PR_USER_THREAD,
TracerThread,
args,
sTracerStartClosure,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,
PR_JOINABLE_THREAD,
@ -241,16 +255,24 @@ bool InitEventTracing(bool aLog)
void ShutdownEventTracing()
{
MOZ_ASSERT(NS_IsMainThread());
// Wait for all starters to tell us they don't need us
sStartCount--;
if (sStartCount > 0)
return;
if (!sTracerThread)
return;
sExit = true;
sExit = 1;
// Ensure that the tracer thread doesn't hang.
SignalTracerThread();
if (sTracerThread)
PR_JoinThread(sTracerThread);
sTracerThread = nullptr;
sTracerStartClosure = nullptr;
// Allow the widget backend to clean up.
CleanUpWidgetTracing();

View File

@ -92,6 +92,9 @@ NS_IMETHODIMP
nsProfiler::StopProfiler()
{
profiler_stop();
#ifdef MOZ_INSTRUMENT_EVENT_LOOP
mozilla::ShutdownEventTracing();
#endif
return NS_OK;
}