mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 04:58:00 +00:00
Bug 1341496 - Part 3: Make CrossProcessSemaphore allocation fallible. r=billm
--HG-- extra : rebase_source : 318d2c835675547acf667ecfb20bb595ea86e59f
This commit is contained in:
parent
227b55240c
commit
d2f04fbaa8
@ -1439,10 +1439,10 @@ class CrossProcessSemaphoreReadLock : public TextureReadLock
|
||||
{
|
||||
public:
|
||||
CrossProcessSemaphoreReadLock()
|
||||
: mSemaphore("TextureReadLock", 1)
|
||||
: mSemaphore(CrossProcessSemaphore::Create("TextureReadLock", 1))
|
||||
{}
|
||||
explicit CrossProcessSemaphoreReadLock(CrossProcessSemaphoreHandle aHandle)
|
||||
: mSemaphore(aHandle)
|
||||
: mSemaphore(CrossProcessSemaphore::Create(aHandle))
|
||||
{}
|
||||
|
||||
virtual bool ReadLock() override
|
||||
@ -1450,30 +1450,30 @@ public:
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
return mSemaphore.Wait();
|
||||
return mSemaphore->Wait();
|
||||
}
|
||||
virtual bool TryReadLock(TimeDuration aTimeout) override
|
||||
{
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
return mSemaphore.Wait(Some(aTimeout));
|
||||
return mSemaphore->Wait(Some(aTimeout));
|
||||
}
|
||||
virtual int32_t ReadUnlock() override
|
||||
{
|
||||
if (!IsValid()) {
|
||||
return 1;
|
||||
}
|
||||
mSemaphore.Signal();
|
||||
mSemaphore->Signal();
|
||||
return 1;
|
||||
}
|
||||
virtual bool IsValid() const override { return true; }
|
||||
virtual bool IsValid() const override { return !!mSemaphore; }
|
||||
|
||||
virtual bool Serialize(ReadLockDescriptor& aOutput, base::ProcessId aOther) override;
|
||||
|
||||
virtual LockType GetType() override { return TYPE_CROSS_PROCESS_SEMAPHORE; }
|
||||
|
||||
CrossProcessSemaphore mSemaphore;
|
||||
UniquePtr<CrossProcessSemaphore> mSemaphore;
|
||||
};
|
||||
|
||||
// static
|
||||
@ -1656,7 +1656,7 @@ bool
|
||||
CrossProcessSemaphoreReadLock::Serialize(ReadLockDescriptor& aOutput, base::ProcessId aOther)
|
||||
{
|
||||
if (IsValid()) {
|
||||
aOutput = ReadLockDescriptor(CrossProcessSemaphoreDescriptor(mSemaphore.ShareToProcess(aOther)));
|
||||
aOutput = ReadLockDescriptor(CrossProcessSemaphoreDescriptor(mSemaphore->ShareToProcess(aOther)));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -45,13 +45,14 @@ public:
|
||||
* CrossProcessSemaphore
|
||||
* @param name A name which can reference this lock (currently unused)
|
||||
**/
|
||||
explicit CrossProcessSemaphore(const char* aName, uint32_t aInitialValue);
|
||||
static CrossProcessSemaphore* Create(const char* aName, uint32_t aInitialValue);
|
||||
|
||||
/**
|
||||
* CrossProcessSemaphore
|
||||
* @param handle A handle of an existing cross process semaphore that can be
|
||||
* opened.
|
||||
*/
|
||||
explicit CrossProcessSemaphore(CrossProcessSemaphoreHandle aHandle);
|
||||
static CrossProcessSemaphore* Create(CrossProcessSemaphoreHandle aHandle);
|
||||
|
||||
~CrossProcessSemaphore();
|
||||
|
||||
@ -85,6 +86,8 @@ private:
|
||||
CrossProcessSemaphore &operator=(const CrossProcessSemaphore&);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
explicit CrossProcessSemaphore(HANDLE aSemaphore);
|
||||
|
||||
HANDLE mSemaphore;
|
||||
#elif !defined(OS_MACOSX)
|
||||
RefPtr<mozilla::ipc::SharedMemoryBasic> mSharedBuffer;
|
||||
|
@ -26,73 +26,84 @@ struct SemaphoreData {
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(const char*, uint32_t aInitialValue)
|
||||
: mSemaphore(nullptr)
|
||||
, mRefCount(nullptr)
|
||||
/* static */ CrossProcessSemaphore*
|
||||
CrossProcessSemaphore::Create(const char*, uint32_t aInitialValue)
|
||||
{
|
||||
mSharedBuffer = new ipc::SharedMemoryBasic;
|
||||
if (!mSharedBuffer->Create(sizeof(SemaphoreData))) {
|
||||
MOZ_CRASH();
|
||||
RefPtr<ipc::SharedMemoryBasic> sharedBuffer = new ipc::SharedMemoryBasic;
|
||||
if (!sharedBuffer->Create(sizeof(SemaphoreData))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mSharedBuffer->Map(sizeof(SemaphoreData))) {
|
||||
MOZ_CRASH();
|
||||
if (!sharedBuffer->Map(sizeof(SemaphoreData))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SemaphoreData* data = static_cast<SemaphoreData*>(mSharedBuffer->memory());
|
||||
SemaphoreData* data = static_cast<SemaphoreData*>(sharedBuffer->memory());
|
||||
|
||||
if (!data) {
|
||||
MOZ_CRASH();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sem_init(&data->mSemaphore, 1, aInitialValue)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CrossProcessSemaphore* sem = new CrossProcessSemaphore;
|
||||
sem->mSharedBuffer = sharedBuffer;
|
||||
sem->mSemaphore = &data->mSemaphore;
|
||||
sem->mRefCount = &data->mRefCount;
|
||||
*sem->mRefCount = 1;
|
||||
|
||||
data->mInitialValue = aInitialValue;
|
||||
mSemaphore = &data->mSemaphore;
|
||||
mRefCount = &data->mRefCount;
|
||||
|
||||
*mRefCount = 1;
|
||||
if (sem_init(mSemaphore, 1, data->mInitialValue)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
MOZ_COUNT_CTOR(CrossProcessSemaphore);
|
||||
return sem;
|
||||
}
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(CrossProcessSemaphoreHandle aHandle)
|
||||
: mSemaphore(nullptr)
|
||||
, mRefCount(nullptr)
|
||||
/* static */ CrossProcessSemaphore*
|
||||
CrossProcessSemaphore::Create(CrossProcessSemaphoreHandle aHandle)
|
||||
{
|
||||
mSharedBuffer = new ipc::SharedMemoryBasic;
|
||||
RefPtr<ipc::SharedMemoryBasic> sharedBuffer = new ipc::SharedMemoryBasic;
|
||||
|
||||
if (!mSharedBuffer->IsHandleValid(aHandle)) {
|
||||
MOZ_CRASH();
|
||||
if (!sharedBuffer->IsHandleValid(aHandle)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mSharedBuffer->SetHandle(aHandle, ipc::SharedMemory::RightsReadWrite)) {
|
||||
MOZ_CRASH();
|
||||
if (!sharedBuffer->SetHandle(aHandle, ipc::SharedMemory::RightsReadWrite)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mSharedBuffer->Map(sizeof(SemaphoreData))) {
|
||||
MOZ_CRASH();
|
||||
if (!sharedBuffer->Map(sizeof(SemaphoreData))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SemaphoreData* data = static_cast<SemaphoreData*>(mSharedBuffer->memory());
|
||||
SemaphoreData* data = static_cast<SemaphoreData*>(sharedBuffer->memory());
|
||||
|
||||
if (!data) {
|
||||
MOZ_CRASH();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSemaphore = &data->mSemaphore;
|
||||
mRefCount = &data->mRefCount;
|
||||
int32_t oldCount = (*mRefCount)++;
|
||||
|
||||
int32_t oldCount = data->mRefCount++;
|
||||
if (oldCount == 0) {
|
||||
// The other side has already let go of their CrossProcessSemaphore, so now
|
||||
// mSemaphore is garbage. We need to re-initialize it.
|
||||
if (sem_init(mSemaphore, 1, data->mInitialValue)) {
|
||||
MOZ_CRASH();
|
||||
if (sem_init(&data->mSemaphore, 1, data->mInitialValue)) {
|
||||
data->mRefCount--;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CrossProcessSemaphore* sem = new CrossProcessSemaphore;
|
||||
sem->mSharedBuffer = sharedBuffer;
|
||||
sem->mSemaphore = &data->mSemaphore;
|
||||
sem->mRefCount = &data->mRefCount;
|
||||
return sem;
|
||||
}
|
||||
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore()
|
||||
: mSemaphore(nullptr)
|
||||
, mRefCount(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CrossProcessSemaphore);
|
||||
}
|
||||
|
||||
|
@ -10,14 +10,23 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(const char*, uint32_t)
|
||||
/* static */ CrossProcessSemaphore*
|
||||
CrossProcessSemaphore::Create(const char*, uint32_t)
|
||||
{
|
||||
MOZ_CRASH("Cross-process semaphores not allowed on this platform.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(CrossProcessSemaphoreHandle)
|
||||
/* static */ CrossProcessSemaphore*
|
||||
CrossProcessSemaphore::Create(CrossProcessSemaphoreHandle)
|
||||
{
|
||||
MOZ_CRASH("Cross-process semaphores not allowed on this platform.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore()
|
||||
{
|
||||
MOZ_CRASH("Cross-process semaphores not allowed on this platform - woah! We should've aborted by now!");
|
||||
}
|
||||
|
||||
CrossProcessSemaphore::~CrossProcessSemaphore()
|
||||
|
@ -17,25 +17,33 @@ using base::ProcessHandle;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(const char*, uint32_t aInitialValue)
|
||||
/* static */ CrossProcessSemaphore*
|
||||
CrossProcessSemaphore::Create(const char*, uint32_t aInitialValue)
|
||||
{
|
||||
// We explicitly share this using DuplicateHandle, we do -not- want this to
|
||||
// be inherited by child processes by default! So no security attributes are
|
||||
// given.
|
||||
mSemaphore = ::CreateSemaphoreA(nullptr, aInitialValue, 0x7fffffff, nullptr);
|
||||
if (!mSemaphore) {
|
||||
MOZ_CRASH("This shouldn't happen - failed to create semaphore!");
|
||||
HANDLE semaphore = ::CreateSemaphoreA(nullptr, aInitialValue, 0x7fffffff, nullptr);
|
||||
if (!semaphore) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_COUNT_CTOR(CrossProcessSemaphore);
|
||||
return new CrossProcessSemaphore(semaphore);
|
||||
}
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(CrossProcessSemaphoreHandle aHandle)
|
||||
/* static */ CrossProcessSemaphore*
|
||||
CrossProcessSemaphore::Create(CrossProcessSemaphoreHandle aHandle)
|
||||
{
|
||||
DWORD flags;
|
||||
if (!::GetHandleInformation(aHandle, &flags)) {
|
||||
MOZ_CRASH("Attempt to construct a semaphore from an invalid handle!");
|
||||
return nullptr;
|
||||
}
|
||||
mSemaphore = aHandle;
|
||||
|
||||
return new CrossProcessSemaphore(aHandle);
|
||||
}
|
||||
|
||||
CrossProcessSemaphore::CrossProcessSemaphore(HANDLE aSemaphore)
|
||||
: mSemaphore(aSemaphore)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CrossProcessSemaphore);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user