pkgsrc-wip/firefox-hg/patches/patch-ipc_glue_CrossProcess...

192 lines
4.8 KiB
C++

$NetBSD: patch-ipc_glue_CrossProcessSemaphore__posix.cpp,v 1.3 2017/09/30 05:34:12 ryoon Exp $
- avoid use of sem_t on NetBSD
http://mail-index.netbsd.org/pkgsrc-bugs/2017/06/23/msg062225.html
--- ipc/glue/CrossProcessSemaphore_posix.cpp.orig 2017-09-14 20:16:01.000000000 +0000
+++ ipc/glue/CrossProcessSemaphore_posix.cpp
@@ -9,6 +9,11 @@
#include "nsDebug.h"
#include "nsISupportsImpl.h"
#include <errno.h>
+#if defined(__NetBSD__)
+#include <iostream>
+#include <unistd.h>
+#include <limits>
+#endif
static const uint64_t kNsPerMs = 1000000;
static const uint64_t kNsPerSec = 1000000000;
@@ -17,7 +22,13 @@ namespace {
struct SemaphoreData {
+#if defined(__NetBSD__)
+ pthread_mutex_t mMutex;
+ pthread_cond_t mNotZero;
+ uint32_t mValue;
+#else
sem_t mSemaphore;
+#endif
mozilla::Atomic<int32_t> mRefCount;
uint32_t mInitialValue;
};
@@ -44,13 +55,27 @@ CrossProcessSemaphore::Create(const char
return nullptr;
}
+#if defined(__NetBSD__)
+ data->mValue = aInitialValue;
+ if (pthread_mutex_init(&data->mMutex, NULL) ||
+ pthread_cond_init(&data->mNotZero, NULL) ) {
+ return nullptr;
+ }
+#else
if (sem_init(&data->mSemaphore, 1, aInitialValue)) {
return nullptr;
}
+#endif
CrossProcessSemaphore* sem = new CrossProcessSemaphore;
sem->mSharedBuffer = sharedBuffer;
+#if defined(__NetBSD__)
+ sem->mMutex = &data->mMutex;
+ sem->mNotZero = &data->mNotZero;
+ sem->mValue = &data->mValue;
+#else
sem->mSemaphore = &data->mSemaphore;
+#endif
sem->mRefCount = &data->mRefCount;
*sem->mRefCount = 1;
@@ -84,24 +109,44 @@ CrossProcessSemaphore::Create(CrossProce
int32_t oldCount = data->mRefCount++;
if (oldCount == 0) {
+#if defined(__NetBSD__)
+ if (pthread_mutex_init(&data->mMutex, NULL) ||
+ pthread_cond_init(&data->mNotZero, NULL) ) {
+ data->mRefCount--;
+ return nullptr;
+ }
+#else
// The other side has already let go of their CrossProcessSemaphore, so now
// mSemaphore is garbage. We need to re-initialize it.
if (sem_init(&data->mSemaphore, 1, data->mInitialValue)) {
data->mRefCount--;
return nullptr;
}
+#endif
}
CrossProcessSemaphore* sem = new CrossProcessSemaphore;
sem->mSharedBuffer = sharedBuffer;
+#if defined(__NetBSD__)
+ sem->mMutex = &data->mMutex;
+ sem->mNotZero = &data->mNotZero;
+ sem->mValue = &data->mValue;
+#else
sem->mSemaphore = &data->mSemaphore;
+#endif
sem->mRefCount = &data->mRefCount;
return sem;
}
CrossProcessSemaphore::CrossProcessSemaphore()
+#if defined(__NetBSD__)
+ : mMutex (nullptr)
+ , mNotZero (nullptr)
+ , mValue (nullptr)
+#else
: mSemaphore(nullptr)
+#endif
, mRefCount(nullptr)
{
MOZ_COUNT_CTOR(CrossProcessSemaphore);
@@ -113,17 +158,58 @@ CrossProcessSemaphore::~CrossProcessSema
if (oldCount == 0) {
// Nothing can be done if the destroy fails so ignore return code.
+#if defined(__NetBSD__)
+ (void)pthread_cond_destroy(mNotZero);
+ (void)pthread_mutex_destroy(mMutex);
+#else
Unused << sem_destroy(mSemaphore);
+#endif
}
MOZ_COUNT_DTOR(CrossProcessSemaphore);
}
+#if defined(__NetBSD__)
+static struct timespec
+makeAbsTime(const Maybe<TimeDuration>& aWaitTime) {
+ struct timespec ts;
+ if (aWaitTime.isSome()) {
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_nsec += (kNsPerMs * aWaitTime->ToMilliseconds());
+ ts.tv_sec += ts.tv_nsec / kNsPerSec;
+ ts.tv_nsec %= kNsPerSec;
+ }
+ else {
+ ts.tv_sec = std::numeric_limits<time_t>::max();
+ ts.tv_nsec = 0;
+ }
+ return ts;
+}
+#endif
+
bool
CrossProcessSemaphore::Wait(const Maybe<TimeDuration>& aWaitTime)
{
MOZ_ASSERT(*mRefCount > 0, "Attempting to wait on a semaphore with zero ref count");
int ret;
+#if defined(__NetBSD__)
+ struct timespec ts = makeAbsTime(aWaitTime);
+
+ ret = pthread_mutex_lock(mMutex);
+
+ if (ret == 0) {
+ while (ret == 0 && mValue == 0) {
+ ret = pthread_cond_timedwait(mNotZero, mMutex, &ts);
+ while (ret == -1 && errno == EINTR) {
+ ret = pthread_cond_timedwait(mNotZero, mMutex, &ts);
+ }
+ }
+ if (ret == 0) {
+ --(*mValue);
+ }
+ pthread_mutex_unlock(mMutex);
+ }
+#else
if (aWaitTime.isSome()) {
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
@@ -140,6 +226,7 @@ CrossProcessSemaphore::Wait(const Maybe<
while ((ret = sem_wait(mSemaphore)) == -1 && errno == EINTR) {
}
}
+#endif
return ret == 0;
}
@@ -147,7 +234,17 @@ void
CrossProcessSemaphore::Signal()
{
MOZ_ASSERT(*mRefCount > 0, "Attempting to signal a semaphore with zero ref count");
+#if defined(__NetBSD__)
+ int ret;
+ ret = pthread_mutex_lock(mMutex);
+ if (ret == 0) {
+ ++(*mValue);
+ pthread_cond_signal(mNotZero);
+ pthread_mutex_unlock(mMutex);
+ }
+#else
sem_post(mSemaphore);
+#endif
}
CrossProcessSemaphoreHandle