pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pkg/51966
The following reply was made to PR pkg/51966; it has been noted by GNATS.
From: aran%100acres.us@localhost
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: pkg/51966
Date: Fri, 23 Jun 2017 14:33:02 -0700 (PDT)
----Next_Part(Fri_Jun_23_14_33_02_2017_562)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
The problem if Firefox's CrossProcessSemaphore. On Linux, sem_t is a opaque
structure. On NetBSD, it is opaque pointer. The sem_t is shared between two
processes. This, of course, does not work on NetBSD.
I change the class mozilla::CrossProcessSemaphore to use pthread primitives to
implement semaphore logic. This works on my system:
$uname -a
NetBSD owl 8.99.1 NetBSD 8.99.1 (GENERIC) #2: Mon Jun 19 21:52:11 PDT 2017 aran@owl:/home/NetBSD/build/sys/arch/amd64/compile/GENERIC amd64
Aran
----Next_Part(Fri_Jun_23_14_33_02_2017_562)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="patch-ipc_glue_CrossProcessSemaphore.h"
$NetBSD$
--- ipc/glue/CrossProcessSemaphore.h.orig 2017-06-05 20:45:20.000000000 +0000
+++ ipc/glue/CrossProcessSemaphore.h
@@ -91,7 +91,9 @@ private:
HANDLE mSemaphore;
#elif !defined(OS_MACOSX)
RefPtr<mozilla::ipc::SharedMemoryBasic> mSharedBuffer;
- sem_t* mSemaphore;
+ pthread_mutex_t* mMutex;
+ pthread_cond_t* mNotZero;
+ uint32_t* mValue;
mozilla::Atomic<int32_t>* mRefCount;
#endif
};
----Next_Part(Fri_Jun_23_14_33_02_2017_562)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="patch-ipc_glue_CrossProcessSemaphore__posix.cpp"
$NetBSD$
--- ipc/glue/CrossProcessSemaphore_posix.cpp.orig 2017-06-05 20:45:20.000000000 +0000
+++ ipc/glue/CrossProcessSemaphore_posix.cpp
@@ -9,15 +9,20 @@
#include "nsDebug.h"
#include "nsISupportsImpl.h"
#include <errno.h>
+#include <iostream>
+#include <unistd.h>
+#include <limits>
static const uint64_t kNsPerMs = 1000000;
static const uint64_t kNsPerSec = 1000000000;
namespace {
-
struct SemaphoreData {
- sem_t mSemaphore;
+ pthread_mutex_t mMutex;
+ pthread_cond_t mNotZero;
+ uint32_t mValue;
+
mozilla::Atomic<int32_t> mRefCount;
uint32_t mInitialValue;
};
@@ -44,15 +49,21 @@ CrossProcessSemaphore::Create(const char
return nullptr;
}
- if (sem_init(&data->mSemaphore, 1, aInitialValue)) {
+ data->mValue = aInitialValue;
+ if (pthread_mutex_init(&data->mMutex, NULL) ||
+ pthread_cond_init(&data->mNotZero, NULL) ) {
return nullptr;
}
CrossProcessSemaphore* sem = new CrossProcessSemaphore;
sem->mSharedBuffer = sharedBuffer;
- sem->mSemaphore = &data->mSemaphore;
- sem->mRefCount = &data->mRefCount;
- *sem->mRefCount = 1;
+ sem->mMutex = &data->mMutex;
+ sem->mNotZero = &data->mNotZero;
+ sem->mValue = &data->mValue;
+ sem->mRefCount = &data->mRefCount;
+ *sem->mRefCount = 1;
+
+// aran_log(*sem->mSemaphore);
data->mInitialValue = aInitialValue;
@@ -77,16 +88,10 @@ CrossProcessSemaphore::Create(CrossProce
}
SemaphoreData* data = static_cast<SemaphoreData*>(sharedBuffer->memory());
-
- if (!data) {
- return nullptr;
- }
-
- int32_t oldCount = data->mRefCount++;
+ int 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(&data->mSemaphore, 1, data->mInitialValue)) {
+ if (pthread_mutex_init(&data->mMutex, NULL) ||
+ pthread_cond_init(&data->mNotZero, NULL) ) {
data->mRefCount--;
return nullptr;
}
@@ -94,14 +99,18 @@ CrossProcessSemaphore::Create(CrossProce
CrossProcessSemaphore* sem = new CrossProcessSemaphore;
sem->mSharedBuffer = sharedBuffer;
- sem->mSemaphore = &data->mSemaphore;
+ sem->mMutex = &data->mMutex;
+ sem->mNotZero = &data->mNotZero;
+ sem->mValue = &data->mValue;
sem->mRefCount = &data->mRefCount;
return sem;
}
CrossProcessSemaphore::CrossProcessSemaphore()
- : mSemaphore(nullptr)
+ : mMutex (nullptr)
+ , mNotZero (nullptr)
+ , mValue (nullptr)
, mRefCount(nullptr)
{
MOZ_COUNT_CTOR(CrossProcessSemaphore);
@@ -113,35 +122,54 @@ CrossProcessSemaphore::~CrossProcessSema
if (oldCount == 0) {
// Nothing can be done if the destroy fails so ignore return code.
- Unused << sem_destroy(mSemaphore);
+ (void)pthread_cond_destroy(mNotZero);
+ (void)pthread_mutex_destroy(mMutex);
}
MOZ_COUNT_DTOR(CrossProcessSemaphore);
}
+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;
+}
+
bool
CrossProcessSemaphore::Wait(const Maybe<TimeDuration>& aWaitTime)
{
MOZ_ASSERT(*mRefCount > 0, "Attempting to wait on a semaphore with zero ref count");
int ret;
- if (aWaitTime.isSome()) {
- struct timespec ts;
- if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
- return false;
- }
-
- ts.tv_nsec += (kNsPerMs * aWaitTime->ToMilliseconds());
- ts.tv_sec += ts.tv_nsec / kNsPerSec;
- ts.tv_nsec %= kNsPerSec;
+ struct timespec ts = makeAbsTime(aWaitTime);
- while ((ret = sem_timedwait(mSemaphore, &ts)) == -1 && errno == EINTR) {
- continue;
+ ret = pthread_mutex_timedlock(mMutex, &ts);
+ while (ret == -1 && errno == EINTR) {
+ ret = pthread_mutex_timedlock(mMutex, &ts);
+ }
+
+ 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);
+ }
}
- } else {
- while ((ret = sem_wait(mSemaphore)) == -1 && errno == EINTR) {
- continue;
+ if(ret == 0) {
+ --(*mValue);
}
+ pthread_mutex_unlock(mMutex);
}
+
return ret == 0;
}
@@ -149,7 +177,16 @@ void
CrossProcessSemaphore::Signal()
{
MOZ_ASSERT(*mRefCount > 0, "Attempting to signal a semaphore with zero ref count");
- sem_post(mSemaphore);
+ int ret;
+ ret = pthread_mutex_lock(mMutex);
+ while(ret == -1 && errno == EINTR) {
+ ret = pthread_mutex_lock(mMutex);
+ }
+ if(ret == 0) {
+ ++(*mValue);
+ pthread_cond_signal(mNotZero);
+ pthread_mutex_unlock(mMutex);
+ }
}
CrossProcessSemaphoreHandle
@@ -160,7 +197,6 @@ CrossProcessSemaphore::ShareToProcess(ba
if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aTargetPid, &result)) {
MOZ_CRASH();
}
-
return result;
}
----Next_Part(Fri_Jun_23_14_33_02_2017_562)----
Home |
Main Index |
Thread Index |
Old Index