mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 806363 - Remove wake locks on content-shutdown. r=jlebar
This commit is contained in:
parent
41e92624f2
commit
5a97ac6956
@ -631,6 +631,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
|
||||
props->Init();
|
||||
|
||||
props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), mChildID);
|
||||
|
||||
if (AbnormalShutdown == why) {
|
||||
props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
|
||||
|
||||
@ -644,9 +646,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
nsAutoString dumpID(crashReporter->ChildDumpID());
|
||||
props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID);
|
||||
#endif
|
||||
|
||||
obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nullptr);
|
||||
}
|
||||
obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nullptr);
|
||||
}
|
||||
|
||||
MessageLoop::current()->
|
||||
@ -702,6 +703,7 @@ ContentParent::ContentParent(const nsAString& aAppManifestURL,
|
||||
ChildOSPrivileges aOSPrivileges)
|
||||
: mSubprocess(nullptr)
|
||||
, mOSPrivileges(aOSPrivileges)
|
||||
, mChildID(-1)
|
||||
, mGeolocationWatchID(-1)
|
||||
, mRunToCompletionDepth(0)
|
||||
, mShouldCallUnblockChild(false)
|
||||
@ -1125,7 +1127,7 @@ bool
|
||||
ContentParent::RecvGetProcessAttributes(uint64_t* aId, bool* aStartBackground,
|
||||
bool* aIsForApp, bool* aIsForBrowser)
|
||||
{
|
||||
*aId = gContentChildID++;
|
||||
*aId = mChildID = gContentChildID++;
|
||||
*aStartBackground =
|
||||
(mAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL);
|
||||
*aIsForApp = IsForApp();
|
||||
|
@ -311,6 +311,7 @@ private:
|
||||
GeckoChildProcessHost* mSubprocess;
|
||||
ChildOSPrivileges mOSPrivileges;
|
||||
|
||||
uint64_t mChildID;
|
||||
int32_t mGeolocationWatchID;
|
||||
int mRunToCompletionDepth;
|
||||
bool mShouldCallUnblockChild;
|
||||
|
20
hal/Hal.cpp
20
hal/Hal.cpp
@ -21,6 +21,7 @@
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "WindowIdentifier.h"
|
||||
#include "mozilla/dom/ScreenOrientation.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <process.h>
|
||||
@ -641,16 +642,29 @@ UnregisterWakeLockObserver(WakeLockObserver* aObserver)
|
||||
}
|
||||
|
||||
void
|
||||
ModifyWakeLock(const nsAString &aTopic,
|
||||
ModifyWakeLock(const nsAString& aTopic,
|
||||
WakeLockControl aLockAdjust,
|
||||
WakeLockControl aHiddenAdjust)
|
||||
{
|
||||
AssertMainThread();
|
||||
PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic, aLockAdjust, aHiddenAdjust));
|
||||
uint64_t processID = InSandbox() ? dom::ContentChild::GetSingleton()->GetID() : 0;
|
||||
PROXY_IF_SANDBOXED(ModifyWakeLockInternal(aTopic, aLockAdjust, aHiddenAdjust, processID));
|
||||
}
|
||||
|
||||
void
|
||||
GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
|
||||
ModifyWakeLockInternal(const nsAString& aTopic,
|
||||
WakeLockControl aLockAdjust,
|
||||
WakeLockControl aHiddenAdjust,
|
||||
uint64_t aProcessID)
|
||||
{
|
||||
AssertMainThread();
|
||||
// TODO: Bug 812403 - support wake locks in nested content processes.
|
||||
AssertMainProcess();
|
||||
PROXY_IF_SANDBOXED(ModifyWakeLockInternal(aTopic, aLockAdjust, aHiddenAdjust, aProcessID));
|
||||
}
|
||||
|
||||
void
|
||||
GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
|
||||
{
|
||||
AssertMainThread();
|
||||
PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
|
||||
|
14
hal/Hal.h
14
hal/Hal.h
@ -340,7 +340,7 @@ void RegisterWakeLockObserver(WakeLockObserver* aObserver);
|
||||
void UnregisterWakeLockObserver(WakeLockObserver* aObserver);
|
||||
|
||||
/**
|
||||
* Adjust the internal wake lock counts.
|
||||
* Adjust the wake lock counts.
|
||||
* @param aTopic lock topic
|
||||
* @param aLockAdjust to increase or decrease active locks
|
||||
* @param aHiddenAdjust to increase or decrease hidden locks
|
||||
@ -349,6 +349,18 @@ void ModifyWakeLock(const nsAString &aTopic,
|
||||
hal::WakeLockControl aLockAdjust,
|
||||
hal::WakeLockControl aHiddenAdjust);
|
||||
|
||||
/**
|
||||
* Adjust the wake lock counts. Do not call this function directly.
|
||||
* @param aTopic lock topic
|
||||
* @param aLockAdjust to increase or decrease active locks
|
||||
* @param aHiddenAdjust to increase or decrease hidden locks
|
||||
* @param aProcessID unique id per-ContentChild or 0 for chrome
|
||||
*/
|
||||
void ModifyWakeLockInternal(const nsAString &aTopic,
|
||||
hal::WakeLockControl aLockAdjust,
|
||||
hal::WakeLockControl aHiddenAdjust,
|
||||
uint64_t aProcessID);
|
||||
|
||||
/**
|
||||
* Query the wake lock numbers of aTopic.
|
||||
* @param aTopic lock topic
|
||||
|
@ -6,9 +6,12 @@
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/HalWakeLock.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsObserverService.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsIPropertyBag2.h"
|
||||
#include "nsObserverService.h"
|
||||
|
||||
using namespace mozilla::hal;
|
||||
|
||||
@ -35,17 +38,44 @@ namespace hal_impl {
|
||||
|
||||
namespace {
|
||||
struct LockCount {
|
||||
LockCount()
|
||||
: numLocks(0)
|
||||
, numHidden(0)
|
||||
{}
|
||||
uint32_t numLocks;
|
||||
uint32_t numHidden;
|
||||
};
|
||||
}
|
||||
typedef nsDataHashtable<nsUint64HashKey, LockCount> ProcessLockTable;
|
||||
typedef nsClassHashtable<nsStringHashKey, ProcessLockTable> LockTable;
|
||||
|
||||
static int sActiveChildren = 0;
|
||||
static nsAutoPtr<nsDataHashtable<nsStringHashKey, LockCount> > sLockTable;
|
||||
static int sActiveListeners = 0;
|
||||
static StaticAutoPtr<LockTable> sLockTable;
|
||||
static bool sInitialized = false;
|
||||
static bool sIsShuttingDown = false;
|
||||
|
||||
namespace {
|
||||
static PLDHashOperator
|
||||
RemoveChildFromList(const nsAString& aKey, ProcessLockTable* aTable, void* aUserArg)
|
||||
{
|
||||
MOZ_ASSERT(aUserArg);
|
||||
|
||||
uint64_t childID = *static_cast<uint64_t*>(aUserArg);
|
||||
aTable->Remove(childID);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CountWakeLocks(const uint64_t& aKey, LockCount aCount, void* aUserArg)
|
||||
{
|
||||
MOZ_ASSERT(aUserArg);
|
||||
|
||||
LockCount* totalCount = static_cast<LockCount*>(aUserArg);
|
||||
totalCount->numLocks += aCount.numLocks;
|
||||
totalCount->numHidden += aCount.numHidden;
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
class ClearHashtableOnShutdown MOZ_FINAL : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -64,37 +94,73 @@ ClearHashtableOnShutdown::Observe(nsISupports* aSubject, const char* aTopic, con
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
class CleanupOnContentShutdown MOZ_FINAL : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(CleanupOnContentShutdown, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CleanupOnContentShutdown::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* data)
|
||||
{
|
||||
MOZ_ASSERT(!strcmp(aTopic, "ipc:content-shutdown"));
|
||||
|
||||
if (sIsShuttingDown) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject);
|
||||
if (!props) {
|
||||
NS_WARNING("ipc:content-shutdown message without property bag as subject");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint64_t childID = 0;
|
||||
nsresult rv = props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"),
|
||||
&childID);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
sLockTable->EnumerateRead(RemoveChildFromList, &childID);
|
||||
} else {
|
||||
NS_WARNING("ipc:content-shutdown message without childID property");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
Init()
|
||||
{
|
||||
sLockTable = new nsDataHashtable<nsStringHashKey, LockCount>();
|
||||
sLockTable = new LockTable();
|
||||
sLockTable->Init();
|
||||
sInitialized = true;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(new ClearHashtableOnShutdown(), "xpcom-shutdown", false);
|
||||
obs->AddObserver(new CleanupOnContentShutdown(), "ipc:content-shutdown", false);
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
EnableWakeLockNotifications()
|
||||
{
|
||||
sActiveChildren++;
|
||||
sActiveListeners++;
|
||||
}
|
||||
|
||||
void
|
||||
DisableWakeLockNotifications()
|
||||
{
|
||||
sActiveChildren--;
|
||||
sActiveListeners--;
|
||||
}
|
||||
|
||||
void
|
||||
ModifyWakeLock(const nsAString &aTopic,
|
||||
hal::WakeLockControl aLockAdjust,
|
||||
hal::WakeLockControl aHiddenAdjust)
|
||||
ModifyWakeLockInternal(const nsAString& aTopic,
|
||||
hal::WakeLockControl aLockAdjust,
|
||||
hal::WakeLockControl aHiddenAdjust,
|
||||
uint64_t aProcessID)
|
||||
{
|
||||
if (sIsShuttingDown) {
|
||||
return;
|
||||
@ -103,39 +169,55 @@ ModifyWakeLock(const nsAString &aTopic,
|
||||
Init();
|
||||
}
|
||||
|
||||
LockCount count;
|
||||
count.numLocks = 0;
|
||||
count.numHidden = 0;
|
||||
sLockTable->Get(aTopic, &count);
|
||||
MOZ_ASSERT(count.numLocks >= count.numHidden);
|
||||
MOZ_ASSERT(aLockAdjust >= 0 || count.numLocks > 0);
|
||||
MOZ_ASSERT(aHiddenAdjust >= 0 || count.numHidden > 0);
|
||||
|
||||
WakeLockState oldState = ComputeWakeLockState(count.numLocks, count.numHidden);
|
||||
|
||||
count.numLocks += aLockAdjust;
|
||||
count.numHidden += aHiddenAdjust;
|
||||
MOZ_ASSERT(count.numLocks >= count.numHidden);
|
||||
|
||||
if (count.numLocks) {
|
||||
sLockTable->Put(aTopic, count);
|
||||
ProcessLockTable* table = sLockTable->Get(aTopic);
|
||||
LockCount processCount;
|
||||
LockCount totalCount;
|
||||
if (!table) {
|
||||
table = new ProcessLockTable();
|
||||
table->Init();
|
||||
sLockTable->Put(aTopic, table);
|
||||
} else {
|
||||
table->Get(aProcessID, &processCount);
|
||||
table->EnumerateRead(CountWakeLocks, &totalCount);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(processCount.numLocks >= processCount.numHidden);
|
||||
MOZ_ASSERT(aLockAdjust >= 0 || processCount.numLocks > 0);
|
||||
MOZ_ASSERT(aHiddenAdjust >= 0 || processCount.numHidden > 0);
|
||||
MOZ_ASSERT(totalCount.numLocks >= totalCount.numHidden);
|
||||
MOZ_ASSERT(aLockAdjust >= 0 || totalCount.numLocks > 0);
|
||||
MOZ_ASSERT(aHiddenAdjust >= 0 || totalCount.numHidden > 0);
|
||||
|
||||
WakeLockState oldState = ComputeWakeLockState(totalCount.numLocks, totalCount.numHidden);
|
||||
|
||||
processCount.numLocks += aLockAdjust;
|
||||
processCount.numHidden += aHiddenAdjust;
|
||||
|
||||
totalCount.numLocks += aLockAdjust;
|
||||
totalCount.numHidden += aHiddenAdjust;
|
||||
|
||||
if (processCount.numLocks) {
|
||||
table->Put(aProcessID, processCount);
|
||||
} else {
|
||||
table->Remove(aProcessID);
|
||||
}
|
||||
if (!totalCount.numLocks) {
|
||||
sLockTable->Remove(aTopic);
|
||||
}
|
||||
|
||||
WakeLockState newState = ComputeWakeLockState(count.numLocks, count.numHidden);
|
||||
WakeLockState newState = ComputeWakeLockState(totalCount.numLocks, totalCount.numHidden);
|
||||
|
||||
if (sActiveChildren && oldState != newState) {
|
||||
if (sActiveListeners && oldState != newState) {
|
||||
WakeLockInformation info;
|
||||
info.numLocks() = count.numLocks;
|
||||
info.numHidden() = count.numHidden;
|
||||
info.numLocks() = totalCount.numLocks;
|
||||
info.numHidden() = totalCount.numHidden;
|
||||
info.topic() = aTopic;
|
||||
NotifyWakeLockChange(info);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
|
||||
GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
|
||||
{
|
||||
if (sIsShuttingDown) {
|
||||
NS_WARNING("You don't want to get wake lock information during xpcom-shutdown!");
|
||||
@ -145,13 +227,17 @@ GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
|
||||
Init();
|
||||
}
|
||||
|
||||
LockCount count;
|
||||
count.numLocks = 0;
|
||||
count.numHidden = 0;
|
||||
sLockTable->Get(aTopic, &count);
|
||||
|
||||
aWakeLockInfo->numLocks() = count.numLocks;
|
||||
aWakeLockInfo->numHidden() = count.numHidden;
|
||||
ProcessLockTable* table = sLockTable->Get(aTopic);
|
||||
if (!table) {
|
||||
aWakeLockInfo->numLocks() = 0;
|
||||
aWakeLockInfo->numHidden() = 0;
|
||||
aWakeLockInfo->topic() = aTopic;
|
||||
return;
|
||||
}
|
||||
LockCount totalCount;
|
||||
table->EnumerateRead(CountWakeLocks, &totalCount);
|
||||
aWakeLockInfo->numLocks() = totalCount.numLocks;
|
||||
aWakeLockInfo->numHidden() = totalCount.numHidden;
|
||||
aWakeLockInfo->topic() = aTopic;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,10 @@ parent:
|
||||
sync GetLight(LightType light)
|
||||
returns (LightConfiguration aConfig, bool status);
|
||||
|
||||
ModifyWakeLock(nsString aTopic, WakeLockControl aLockAdjust, WakeLockControl aHiddenAdjust);
|
||||
ModifyWakeLock(nsString aTopic,
|
||||
WakeLockControl aLockAdjust,
|
||||
WakeLockControl aHiddenAdjust,
|
||||
uint64_t aProcessID);
|
||||
EnableWakeLockNotifications();
|
||||
DisableWakeLockNotifications();
|
||||
sync GetWakeLockInfo(nsString aTopic)
|
||||
|
@ -276,9 +276,12 @@ DisableWakeLockNotifications()
|
||||
}
|
||||
|
||||
void
|
||||
ModifyWakeLock(const nsAString &aTopic, WakeLockControl aLockAdjust, WakeLockControl aHiddenAdjust)
|
||||
ModifyWakeLockInternal(const nsAString &aTopic,
|
||||
WakeLockControl aLockAdjust,
|
||||
WakeLockControl aHiddenAdjust,
|
||||
uint64_t aProcessID)
|
||||
{
|
||||
Hal()->SendModifyWakeLock(nsString(aTopic), aLockAdjust, aHiddenAdjust);
|
||||
Hal()->SendModifyWakeLock(nsString(aTopic), aLockAdjust, aHiddenAdjust, aProcessID);
|
||||
}
|
||||
|
||||
void
|
||||
@ -703,12 +706,13 @@ public:
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvModifyWakeLock(const nsString &aTopic,
|
||||
const WakeLockControl &aLockAdjust,
|
||||
const WakeLockControl &aHiddenAdjust) MOZ_OVERRIDE
|
||||
RecvModifyWakeLock(const nsString& aTopic,
|
||||
const WakeLockControl& aLockAdjust,
|
||||
const WakeLockControl& aHiddenAdjust,
|
||||
const uint64_t& aProcessID) MOZ_OVERRIDE
|
||||
{
|
||||
// We allow arbitrary content to use wake locks.
|
||||
hal::ModifyWakeLock(aTopic, aLockAdjust, aHiddenAdjust);
|
||||
hal::ModifyWakeLockInternal(aTopic, aLockAdjust, aHiddenAdjust, aProcessID);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user