| @@ -21,15 +21,19 @@ | |||||
| #include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
| #include <ctime> | #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" { | extern "C" { | ||||
| # include "osx_sem_timedwait.c" | |||||
| # include "osx_sem_timedwait.c" | |||||
| }; | }; | ||||
| # endif | |||||
| #endif | #endif | ||||
| /* | /* | ||||
| @@ -38,7 +42,19 @@ extern "C" { | |||||
| static inline | static inline | ||||
| sem_t* carla_sem_create() noexcept | 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; | static ulong sCounter = 0; | ||||
| ++sCounter; | ++sCounter; | ||||
| @@ -77,7 +93,10 @@ void carla_sem_destroy(sem_t* const sem) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr,); | 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); | ::sem_close(sem); | ||||
| #else | #else | ||||
| // we can't call "sem_destroy(sem)" directly because it will free memory which we allocated during carla_sem_create() | // 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; | sem_t sem2; | ||||
| std::memcpy(&sem2, sem, sizeof(sem_t)); | std::memcpy(&sem2, sem, sizeof(sem_t)); | ||||
| // destroy semaphore | |||||
| ::sem_destroy(&sem2); | |||||
| // free memory allocated in carla_sem_create() | // free memory allocated in carla_sem_create() | ||||
| // FIXME | // FIXME | ||||
| //std::free(sem); | //std::free(sem); | ||||
| // destroy semaphore | |||||
| ::sem_destroy(&sem2); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -104,7 +123,11 @@ bool carla_sem_post(sem_t* const sem) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | ||||
| #ifdef CARLA_OS_WIN | |||||
| return (::ReleaseSemaphore(sem->handle, 1, nullptr) != FALSE); | |||||
| #else | |||||
| return (::sem_post(sem) == 0); | 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(sem != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(secs > 0, 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; | timespec timeout; | ||||
| #ifdef CARLA_OS_LINUX | |||||
| # ifdef CARLA_OS_LINUX | |||||
| ::clock_gettime(CLOCK_REALTIME, &timeout); | ::clock_gettime(CLOCK_REALTIME, &timeout); | ||||
| #else | |||||
| # else | |||||
| timeval now; | timeval now; | ||||
| ::gettimeofday(&now, nullptr); | ::gettimeofday(&now, nullptr); | ||||
| timeout.tv_sec = now.tv_sec; | timeout.tv_sec = now.tv_sec; | ||||
| timeout.tv_nsec = now.tv_usec * 1000; | timeout.tv_nsec = now.tv_usec * 1000; | ||||
| #endif | |||||
| # endif | |||||
| timeout.tv_sec += static_cast<time_t>(secs); | timeout.tv_sec += static_cast<time_t>(secs); | ||||
| try { | try { | ||||
| return (::sem_timedwait(sem, &timeout) == 0); | return (::sem_timedwait(sem, &timeout) == 0); | ||||
| } CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false); | } CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false); | ||||
| #endif | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||