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