mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 895358 - Part 1, Adding POSIX cross process mutex to support progressive tile rendering in B2G; r=khuey
This commit is contained in:
parent
da4f6206c0
commit
7830c75063
@ -9,6 +9,12 @@
|
||||
#include "base/process.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include <pthread.h>
|
||||
#include "SharedMemoryBasic.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#endif
|
||||
|
||||
namespace IPC {
|
||||
template<typename T>
|
||||
struct ParamTraits;
|
||||
@ -27,6 +33,8 @@ struct ParamTraits;
|
||||
namespace mozilla {
|
||||
#ifdef XP_WIN
|
||||
typedef HANDLE CrossProcessMutexHandle;
|
||||
#elif defined(OS_LINUX)
|
||||
typedef mozilla::ipc::SharedMemoryBasic::Handle CrossProcessMutexHandle;
|
||||
#else
|
||||
// Stub for other platforms. We can't use uintptr_t here since different
|
||||
// processes could disagree on its size.
|
||||
@ -91,6 +99,10 @@ private:
|
||||
|
||||
#ifdef XP_WIN
|
||||
HANDLE mMutex;
|
||||
#elif defined(OS_LINUX)
|
||||
mozilla::ipc::SharedMemoryBasic* mSharedBuffer;
|
||||
pthread_mutex_t* mMutex;
|
||||
mozilla::Atomic<int32_t>* mCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
131
ipc/glue/CrossProcessMutex_posix.cpp
Normal file
131
ipc/glue/CrossProcessMutex_posix.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CrossProcessMutex.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct MutexData {
|
||||
pthread_mutex_t mMutex;
|
||||
mozilla::Atomic<int32_t> mCount;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
CrossProcessMutex::CrossProcessMutex(const char*)
|
||||
: mSharedBuffer(nullptr)
|
||||
, mMutex(nullptr)
|
||||
, mCount(nullptr)
|
||||
{
|
||||
mSharedBuffer = new ipc::SharedMemoryBasic;
|
||||
if (!mSharedBuffer->Create(sizeof(MutexData))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
if (!mSharedBuffer->Map(sizeof(MutexData))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
|
||||
|
||||
if (!data) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
mMutex = &(data->mMutex);
|
||||
mCount = &(data->mCount);
|
||||
|
||||
*mCount = 1;
|
||||
|
||||
pthread_mutexattr_t mutexAttributes;
|
||||
pthread_mutexattr_init(&mutexAttributes);
|
||||
// Make the mutex reentrant so it behaves the same as a win32 mutex
|
||||
if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
if (pthread_mutex_init(mMutex, &mutexAttributes)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
MOZ_COUNT_CTOR(CrossProcessMutex);
|
||||
}
|
||||
|
||||
CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
|
||||
: mSharedBuffer(nullptr)
|
||||
, mMutex(nullptr)
|
||||
, mCount(nullptr)
|
||||
{
|
||||
if (!ipc::SharedMemoryBasic::IsHandleValid(aHandle)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
mSharedBuffer = new ipc::SharedMemoryBasic(aHandle);
|
||||
|
||||
if (!mSharedBuffer->Map(sizeof(MutexData))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
|
||||
|
||||
if (!data) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
mMutex = &(data->mMutex);
|
||||
mCount = &(data->mCount);
|
||||
(*mCount)++;
|
||||
|
||||
MOZ_COUNT_CTOR(CrossProcessMutex);
|
||||
}
|
||||
|
||||
CrossProcessMutex::~CrossProcessMutex()
|
||||
{
|
||||
int32_t count = --(*mCount);
|
||||
|
||||
if (count == 0) {
|
||||
// Nothing can be done if the destroy fails so ignore return code.
|
||||
unused << pthread_mutex_destroy(mMutex);
|
||||
}
|
||||
|
||||
delete mSharedBuffer;
|
||||
MOZ_COUNT_DTOR(CrossProcessMutex);
|
||||
}
|
||||
|
||||
void
|
||||
CrossProcessMutex::Lock()
|
||||
{
|
||||
MOZ_ASSERT(*mCount > 0, "Attempting to lock mutex with zero ref count");
|
||||
pthread_mutex_lock(mMutex);
|
||||
}
|
||||
|
||||
void
|
||||
CrossProcessMutex::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(*mCount > 0, "Attempting to unlock mutex with zero ref count");
|
||||
pthread_mutex_unlock(mMutex);
|
||||
}
|
||||
|
||||
CrossProcessMutexHandle
|
||||
CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle)
|
||||
{
|
||||
CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
|
||||
|
||||
if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aHandle, &result)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -35,7 +35,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
'Transport_win.h',
|
||||
]
|
||||
SOURCES += [
|
||||
'CrossProcessMutex_windows.cpp',
|
||||
'SharedMemory_windows.cpp',
|
||||
'Transport_win.cpp',
|
||||
'WindowsMessageLoop.cpp',
|
||||
@ -45,11 +44,23 @@ else:
|
||||
'Transport_posix.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'CrossProcessMutex_unimplemented.cpp',
|
||||
'SharedMemory_posix.cpp',
|
||||
'Transport_posix.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
UNIFIED_SOURCES += [
|
||||
'CrossProcessMutex_windows.cpp',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'Linux':
|
||||
UNIFIED_SOURCES += [
|
||||
'CrossProcessMutex_posix.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'CrossProcessMutex_unimplemented.cpp',
|
||||
]
|
||||
|
||||
# Android has its own,
|
||||
# almost-but-not-quite-compatible-with-POSIX-or-/dev/shm shared memory
|
||||
# impl.
|
||||
|
Loading…
Reference in New Issue
Block a user