Skip to content

Commit

Permalink
add compatibility std::condition_variable semaphore when posix semaph…
Browse files Browse the repository at this point in the history
…ores not available
  • Loading branch information
kdt3rd authored and nickrasmussen committed Aug 8, 2018
1 parent 01680dc commit b6dc2a6
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 19 deletions.
49 changes: 32 additions & 17 deletions IlmBase/IlmThread/IlmThreadSemaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,22 @@
#include "IlmThreadNamespace.h"

#if defined _WIN32 || defined _WIN64
#ifdef NOMINMAX
#undef NOMINMAX
#endif
#define NOMINMAX
#include <windows.h>
#elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
#include <pthread.h>
#elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
#include <semaphore.h>
# ifdef NOMINMAX
# undef NOMINMAX
# endif
# define NOMINMAX
# include <windows.h>
#elif HAVE_POSIX_SEMAPHORES
# include <semaphore.h>
#else
# ifdef ILMBASE_FORCE_CXX03
# if HAVE_PTHREAD
# include <pthread.h>
# endif
# else
# include <mutex>
# include <condition_variable>
# endif
#endif

ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
Expand All @@ -75,12 +82,15 @@ class ILMTHREAD_EXPORT Semaphore

private:

#if defined _WIN32 || defined _WIN64
#if defined _WIN32 || defined _WIN64

mutable HANDLE _semaphore;

#elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
#elif defined(HAVE_POSIX_SEMAPHORES)

mutable sem_t _semaphore;

#else
//
// If the platform has Posix threads but no semapohores,
// then we implement them ourselves using condition variables
Expand All @@ -90,17 +100,22 @@ class ILMTHREAD_EXPORT Semaphore
{
unsigned int count;
unsigned long numWaiting;
# if ILMBASE_FORCE_CXX03
# if HAVE_PTHREAD
pthread_mutex_t mutex;
pthread_cond_t nonZero;
# else
# error unhandled legacy setup
# endif
# else
std::mutex mutex;
std::condition_variable nonZero;
# endif
};

mutable sema_t _semaphore;

#elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES

mutable sem_t _semaphore;

#endif

#endif

void operator = (const Semaphore& s); // not implemented
Semaphore (const Semaphore& s); // not implemented
Expand Down
67 changes: 65 additions & 2 deletions IlmBase/IlmThread/IlmThreadSemaphorePosixCompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@

#include "IlmBaseConfig.h"

#if HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
#if (!HAVE_POSIX_SEMAPHORES) && !defined (_WIN32) && ! defined (_WIN64)

#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <assert.h>

ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER


#if ILMBASE_FORCE_CXX03 && HAVE_PTHREAD
Semaphore::Semaphore (unsigned int value)
{
if (int error = ::pthread_mutex_init (&_semaphore.mutex, 0))
Expand Down Expand Up @@ -157,8 +157,71 @@ Semaphore::value () const
::pthread_mutex_unlock (&_semaphore.mutex);
return value;
}
#else
Semaphore::Semaphore (unsigned int value)
{
_semaphore.count = value;
_semaphore.numWaiting = 0;
}


Semaphore::~Semaphore ()
{
}


void
Semaphore::wait ()
{
std::unique_lock<std::mutex> lk(_semaphore.mutex);

_semaphore.numWaiting++;

while (_semaphore.count == 0)
_semaphore.nonZero.wait (lk);

_semaphore.numWaiting--;
_semaphore.count--;
}


bool
Semaphore::tryWait ()
{
std::lock_guard<std::mutex> lk(_semaphore.mutex);

if (_semaphore.count == 0)
return false;

_semaphore.count--;
return true;
}


void
Semaphore::post ()
{
std::lock_guard<std::mutex> lk(_semaphore.mutex);

_semaphore.count++;
if (_semaphore.numWaiting > 0)
{
if (_semaphore.count > 1)
_semaphore.nonZero.notify_all();
else
_semaphore.nonZero.notify_one();
}
}


int
Semaphore::value () const
{
std::lock_guard<std::mutex> lk(_semaphore.mutex);
return _semaphore.count;
}
#endif

ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT

#endif

0 comments on commit b6dc2a6

Please sign in to comment.