mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1062293 - Add specialized logging to track the lifetime state change of MediaStreamGraphs r=jesup
As noted in the comment, it is very useful to have this interleaved with the ADB logcat on Android/b2g, because this way we can correlate gecko state with the state of the Android HAL. --HG-- extra : rebase_source : 80df45d0851a06daac3abeab2ea4b5bc7e58a21d
This commit is contained in:
parent
fe5fcf8f71
commit
150f294c71
@ -17,6 +17,20 @@ extern PRLogModuleInfo* gMediaStreamGraphLog;
|
|||||||
#define STREAM_LOG(type, msg)
|
#define STREAM_LOG(type, msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// We don't use NSPR log here because we want this interleaved with adb logcat
|
||||||
|
// on Android/B2G
|
||||||
|
// #define ENABLE_LIFECYCLE_LOG
|
||||||
|
#ifdef ENABLE_LIFECYCLE_LOG
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include "android/log.h"
|
||||||
|
#define LIFECYCLE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG" , ## __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
|
||||||
|
#else
|
||||||
|
#define LIFECYCLE_LOG(...) printf(__VA_ARGS__);printf("\n");
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define LIFECYCLE_LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
struct AutoProfilerUnregisterThread
|
struct AutoProfilerUnregisterThread
|
||||||
@ -68,7 +82,9 @@ void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
|
|||||||
void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
|
void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
|
||||||
{
|
{
|
||||||
|
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Switching to new driver: %p (%s)", aNextDriver, aNextDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
|
LIFECYCLE_LOG("Switching to new driver: %p (%s)",
|
||||||
|
aNextDriver, aNextDriver->AsAudioCallbackDriver() ?
|
||||||
|
"AudioCallbackDriver" : "SystemClockDriver");
|
||||||
// Sometimes we switch twice to a new driver per iteration, this is probably a
|
// Sometimes we switch twice to a new driver per iteration, this is probably a
|
||||||
// bug.
|
// bug.
|
||||||
MOZ_ASSERT(!mNextDriver || !mNextDriver->AsAudioCallbackDriver());
|
MOZ_ASSERT(!mNextDriver || !mNextDriver->AsAudioCallbackDriver());
|
||||||
@ -135,15 +151,20 @@ public:
|
|||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
LIFECYCLE_LOG("MediaStreamGraphShutdownThreadRunnable for graph %p",
|
||||||
|
mDriver->GraphImpl());
|
||||||
// We can't release an audio driver on the main thread, because it can be
|
// We can't release an audio driver on the main thread, because it can be
|
||||||
// blocking.
|
// blocking.
|
||||||
if (mDriver->AsAudioCallbackDriver()) {
|
if (mDriver->AsAudioCallbackDriver()) {
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Releasing audio driver off main thread.\n"));
|
LIFECYCLE_LOG("Releasing audio driver off main thread.");
|
||||||
nsRefPtr<AsyncCubebTask> releaseEvent =
|
nsRefPtr<AsyncCubebTask> releaseEvent =
|
||||||
new AsyncCubebTask(mDriver->AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
|
new AsyncCubebTask(mDriver->AsAudioCallbackDriver(),
|
||||||
|
AsyncCubebTask::SHUTDOWN);
|
||||||
mDriver = nullptr;
|
mDriver = nullptr;
|
||||||
releaseEvent->Dispatch();
|
releaseEvent->Dispatch();
|
||||||
} else {
|
} else {
|
||||||
|
LIFECYCLE_LOG("Dropping driver reference for SystemClockDriver.");
|
||||||
mDriver = nullptr;
|
mDriver = nullptr;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -163,7 +184,13 @@ public:
|
|||||||
char aLocal;
|
char aLocal;
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Starting system thread"));
|
STREAM_LOG(PR_LOG_DEBUG, ("Starting system thread"));
|
||||||
profiler_register_thread("MediaStreamGraph", &aLocal);
|
profiler_register_thread("MediaStreamGraph", &aLocal);
|
||||||
|
LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
|
||||||
|
mDriver->mGraphImpl);
|
||||||
if (mDriver->mPreviousDriver) {
|
if (mDriver->mPreviousDriver) {
|
||||||
|
LIFECYCLE_LOG("%p releasing an AudioCallbackDriver(%p), for graph %p\n",
|
||||||
|
mDriver,
|
||||||
|
mDriver->mPreviousDriver.get(),
|
||||||
|
mDriver->GraphImpl());
|
||||||
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
|
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
|
||||||
// Stop and release the previous driver off-main-thread.
|
// Stop and release the previous driver off-main-thread.
|
||||||
nsRefPtr<AsyncCubebTask> releaseEvent =
|
nsRefPtr<AsyncCubebTask> releaseEvent =
|
||||||
@ -185,6 +212,7 @@ private:
|
|||||||
void
|
void
|
||||||
ThreadedDriver::Start()
|
ThreadedDriver::Start()
|
||||||
{
|
{
|
||||||
|
LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl);
|
||||||
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
|
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
|
||||||
NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event);
|
NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event);
|
||||||
}
|
}
|
||||||
@ -432,14 +460,17 @@ AsyncCubebTask::Run()
|
|||||||
|
|
||||||
switch(mOperation) {
|
switch(mOperation) {
|
||||||
case AsyncCubebOperation::INIT:
|
case AsyncCubebOperation::INIT:
|
||||||
|
LIFECYCLE_LOG("AsyncCubebOperation::INIT\n");
|
||||||
mDriver->Init();
|
mDriver->Init();
|
||||||
break;
|
break;
|
||||||
case AsyncCubebOperation::SHUTDOWN:
|
case AsyncCubebOperation::SHUTDOWN:
|
||||||
|
LIFECYCLE_LOG("AsyncCubebOperation::SHUTDOWN\n");
|
||||||
mDriver->Stop();
|
mDriver->Stop();
|
||||||
mDriver = nullptr;
|
mDriver = nullptr;
|
||||||
break;
|
break;
|
||||||
case AsyncCubebOperation::SLEEP: {
|
case AsyncCubebOperation::SLEEP: {
|
||||||
{
|
{
|
||||||
|
LIFECYCLE_LOG("AsyncCubebOperation::SLEEP\n");
|
||||||
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
|
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
|
||||||
// We might just have been awoken
|
// We might just have been awoken
|
||||||
if (mDriver->mNeedAnotherIteration) {
|
if (mDriver->mNeedAnotherIteration) {
|
||||||
@ -797,7 +828,7 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!stillProcessing) {
|
if (!stillProcessing) {
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Stopping audio thread for MediaStreamGraph %p", this));
|
LIFECYCLE_LOG("Stopping audio thread for MediaStreamGraph %p", this);
|
||||||
return aFrames - 1;
|
return aFrames - 1;
|
||||||
}
|
}
|
||||||
return aFrames;
|
return aFrames;
|
||||||
|
@ -187,6 +187,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
void EnsureNextIterationLocked();
|
void EnsureNextIterationLocked();
|
||||||
|
|
||||||
|
MediaStreamGraphImpl* GraphImpl() {
|
||||||
|
return mGraphImpl;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Time of the start of this graph iteration.
|
// Time of the start of this graph iteration.
|
||||||
GraphTime mIterationStart;
|
GraphTime mIterationStart;
|
||||||
|
@ -45,6 +45,21 @@ PRLogModuleInfo* gMediaStreamGraphLog;
|
|||||||
#define STREAM_LOG(type, msg)
|
#define STREAM_LOG(type, msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// #define ENABLE_LIFECYCLE_LOG
|
||||||
|
|
||||||
|
// We don't use NSPR log here because we want this interleaved with adb logcat
|
||||||
|
// on Android/B2G
|
||||||
|
#ifdef ENABLE_LIFECYCLE_LOG
|
||||||
|
# ifdef ANDROID
|
||||||
|
# include "android/log.h"
|
||||||
|
# define LIFECYCLE_LOG(...) __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG", ## __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
|
||||||
|
# else
|
||||||
|
# define LIFECYCLE_LOG(...) printf(__VA_ARGS__);printf("\n");
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define LIFECYCLE_LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The singleton graph instance.
|
* The singleton graph instance.
|
||||||
*/
|
*/
|
||||||
@ -55,6 +70,7 @@ MediaStreamGraphImpl::~MediaStreamGraphImpl()
|
|||||||
NS_ASSERTION(IsEmpty(),
|
NS_ASSERTION(IsEmpty(),
|
||||||
"All streams should have been destroyed by messages from the main thread");
|
"All streams should have been destroyed by messages from the main thread");
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("MediaStreamGraph %p destroyed", this));
|
STREAM_LOG(PR_LOG_DEBUG, ("MediaStreamGraph %p destroyed", this));
|
||||||
|
LIFECYCLE_LOG("MediaStreamGraphImpl::~MediaStreamGraphImpl\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1456,7 +1472,7 @@ public:
|
|||||||
NS_ASSERTION(mGraph->mDetectedNotRunning,
|
NS_ASSERTION(mGraph->mDetectedNotRunning,
|
||||||
"We should know the graph thread control loop isn't running!");
|
"We should know the graph thread control loop isn't running!");
|
||||||
|
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Shutting down graph %p", mGraph.get()));
|
LIFECYCLE_LOG("Shutting down graph %p", mGraph.get());
|
||||||
|
|
||||||
if (mGraph->CurrentDriver()->AsAudioCallbackDriver()) {
|
if (mGraph->CurrentDriver()->AsAudioCallbackDriver()) {
|
||||||
MOZ_ASSERT(!mGraph->CurrentDriver()->AsAudioCallbackDriver()->InCallback());
|
MOZ_ASSERT(!mGraph->CurrentDriver()->AsAudioCallbackDriver()->InCallback());
|
||||||
@ -1559,6 +1575,23 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||||||
mPostedRunInStableStateEvent = false;
|
mPostedRunInStableStateEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_LIFECYCLE_LOG
|
||||||
|
// This should be kept in sync with the LifecycleState enum in
|
||||||
|
// MediaStreamGraphImpl.h
|
||||||
|
const char * LifecycleState_str[] = {
|
||||||
|
"LIFECYCLE_THREAD_NOT_STARTED",
|
||||||
|
"LIFECYCLE_RUNNING",
|
||||||
|
"LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP",
|
||||||
|
"LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN",
|
||||||
|
"LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mLifecycleState != LIFECYCLE_RUNNING) {
|
||||||
|
LIFECYCLE_LOG("Running %p in stable state. Current state: %s\n",
|
||||||
|
this, LifecycleState_str[mLifecycleState]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
runnables.SwapElements(mUpdateRunnables);
|
runnables.SwapElements(mUpdateRunnables);
|
||||||
for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
|
for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
|
||||||
StreamUpdate* update = &mStreamUpdates[i];
|
StreamUpdate* update = &mStreamUpdates[i];
|
||||||
@ -1572,7 +1605,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||||||
if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && IsEmpty()) {
|
if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && IsEmpty()) {
|
||||||
// Complete shutdown. First, ensure that this graph is no longer used.
|
// Complete shutdown. First, ensure that this graph is no longer used.
|
||||||
// A new graph graph will be created if one is needed.
|
// A new graph graph will be created if one is needed.
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Disconnecting MediaStreamGraph %p", this));
|
LIFECYCLE_LOG("Disconnecting MediaStreamGraph %p", this);
|
||||||
if (this == gGraph) {
|
if (this == gGraph) {
|
||||||
// null out gGraph if that's the graph being shut down
|
// null out gGraph if that's the graph being shut down
|
||||||
gGraph = nullptr;
|
gGraph = nullptr;
|
||||||
@ -1581,6 +1614,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||||||
// synchronously because it spins the event loop waiting for threads
|
// synchronously because it spins the event loop waiting for threads
|
||||||
// to shut down, and we don't want to do that in a stable state handler.
|
// to shut down, and we don't want to do that in a stable state handler.
|
||||||
mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
|
mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
|
||||||
|
LIFECYCLE_LOG("Sending MediaStreamGraphShutDownRunnable %p", this);
|
||||||
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this );
|
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this );
|
||||||
NS_DispatchToMainThread(event);
|
NS_DispatchToMainThread(event);
|
||||||
}
|
}
|
||||||
@ -1605,6 +1639,9 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||||||
// or it might exit immediately.
|
// or it might exit immediately.
|
||||||
{
|
{
|
||||||
MonitorAutoUnlock unlock(mMonitor);
|
MonitorAutoUnlock unlock(mMonitor);
|
||||||
|
LIFECYCLE_LOG("Reviving a graph (%p) ! %s\n",
|
||||||
|
this, CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
|
||||||
|
"SystemDriver");
|
||||||
CurrentDriver()->Revive();
|
CurrentDriver()->Revive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1622,7 +1659,10 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||||||
// We should exit the monitor for now, because starting a stream might
|
// We should exit the monitor for now, because starting a stream might
|
||||||
// take locks, and we don't want to deadlock.
|
// take locks, and we don't want to deadlock.
|
||||||
MonitorAutoUnlock unlock(mMonitor);
|
MonitorAutoUnlock unlock(mMonitor);
|
||||||
STREAM_LOG(PR_LOG_DEBUG, ("Starting a graph ! %s\n", CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" : "SystemDriver"));
|
LIFECYCLE_LOG("Starting a graph (%p) ! %s\n",
|
||||||
|
this,
|
||||||
|
CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
|
||||||
|
"SystemDriver");
|
||||||
CurrentDriver()->Start();
|
CurrentDriver()->Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,6 +520,9 @@ public:
|
|||||||
* is not deleted. New messages for the graph are processed synchronously on
|
* is not deleted. New messages for the graph are processed synchronously on
|
||||||
* the main thread if necessary. When the last stream is destroyed, the
|
* the main thread if necessary. When the last stream is destroyed, the
|
||||||
* graph object is deleted.
|
* graph object is deleted.
|
||||||
|
*
|
||||||
|
* This should be kept in sync with the LifecycleState_str array in
|
||||||
|
* MediaStreamGraph.cpp
|
||||||
*/
|
*/
|
||||||
enum LifecycleState {
|
enum LifecycleState {
|
||||||
// The graph thread hasn't started yet.
|
// The graph thread hasn't started yet.
|
||||||
|
Loading…
Reference in New Issue
Block a user