Browse Source

Win32 semaphore implementation (instead of pthreads)

tags/1.9.6
falkTX 10 years ago
parent
commit
42142f3a9c
1 changed files with 53 additions and 14 deletions
  1. +53
    -14
      source/utils/CarlaSemUtils.hpp

+ 53
- 14
source/utils/CarlaSemUtils.hpp View File

@@ -21,15 +21,19 @@
#include "CarlaUtils.hpp"

#include <ctime>
#include <sys/time.h>
#include <sys/types.h>
#include <semaphore.h>

#if defined(CARLA_OS_MAC)
# include <fcntl.h>
#ifdef CARLA_OS_WIN
struct sem_t { HANDLE handle; };
#else
# include <sys/time.h>
# include <sys/types.h>
# include <semaphore.h>
# ifdef CARLA_OS_MAC
# include <fcntl.h>
extern "C" {
# include "osx_sem_timedwait.c"
# include "osx_sem_timedwait.c"
};
# endif
#endif

/*
@@ -38,7 +42,19 @@ extern "C" {
static inline
sem_t* carla_sem_create() noexcept
{
#if defined(CARLA_OS_MAC)
#if defined(CARLA_OS_WIN)
sem_t* const sem = (sem_t*)std::malloc(sizeof(sem_t));
CARLA_SAFE_ASSERT_RETURN(sem != nullptr, nullptr);

SECURITY_ATTRIBUTES sa;
carla_zeroStruct(sa);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;

sem->handle = ::CreateSemaphore(&sa, 0, 1, nullptr);

return sem;
#elif defined(CARLA_OS_MAC)
static ulong sCounter = 0;
++sCounter;

@@ -77,7 +93,10 @@ void carla_sem_destroy(sem_t* const sem) noexcept
{
CARLA_SAFE_ASSERT_RETURN(sem != nullptr,);

#if defined(CARLA_OS_MAC)
#if defined(CARLA_OS_WIN)
::CloseHandle(sem->handle);
std::free(sem);
#elif defined(CARLA_OS_MAC)
::sem_close(sem);
#else
// we can't call "sem_destroy(sem)" directly because it will free memory which we allocated during carla_sem_create()
@@ -87,12 +106,12 @@ void carla_sem_destroy(sem_t* const sem) noexcept
sem_t sem2;
std::memcpy(&sem2, sem, sizeof(sem_t));

// destroy semaphore
::sem_destroy(&sem2);

// free memory allocated in carla_sem_create()
// FIXME
//std::free(sem);

// destroy semaphore
::sem_destroy(&sem2);
#endif
}

@@ -104,7 +123,11 @@ bool carla_sem_post(sem_t* const sem) noexcept
{
CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false);

#ifdef CARLA_OS_WIN
return (::ReleaseSemaphore(sem->handle, 1, nullptr) != FALSE);
#else
return (::sem_post(sem) == 0);
#endif
}

/*
@@ -116,20 +139,36 @@ bool carla_sem_timedwait(sem_t* const sem, const uint secs) noexcept
CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(secs > 0, false);

#if defined(CARLA_OS_WIN)
const DWORD result = ::WaitForSingleObject(sem->handle, secs*1000);

switch (result)
{
case WAIT_OBJECT_0:
return true;
case WAIT_TIMEOUT:
errno = ETIMEDOUT;
return false;
default:
errno = EINTR;
return false;
}
#else
timespec timeout;
#ifdef CARLA_OS_LINUX
# ifdef CARLA_OS_LINUX
::clock_gettime(CLOCK_REALTIME, &timeout);
#else
# else
timeval now;
::gettimeofday(&now, nullptr);
timeout.tv_sec = now.tv_sec;
timeout.tv_nsec = now.tv_usec * 1000;
#endif
# endif
timeout.tv_sec += static_cast<time_t>(secs);

try {
return (::sem_timedwait(sem, &timeout) == 0);
} CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false);
#endif
}

// -----------------------------------------------------------------------


Loading…
Cancel
Save