|
|
@@ -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 |
|
|
|
} |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|