| @@ -221,7 +221,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||||
| setRingBuffer(nullptr, false); | setRingBuffer(nullptr, false); | ||||
| } | } | ||||
| bool waitForServer(const int secs) noexcept | |||||
| bool waitForServer(const uint secs) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | ||||
| @@ -2200,7 +2200,7 @@ private: | |||||
| waitForServer(); | waitForServer(); | ||||
| } | } | ||||
| bool waitForServer(const int secs = 5) | |||||
| bool waitForServer(const uint secs = 5) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(! fTimedOut, false); | CARLA_SAFE_ASSERT_RETURN(! fTimedOut, false); | ||||
| @@ -391,9 +391,9 @@ __cdecl bool jackbridge_remove_all_properties(jack_client_t* client); | |||||
| __cdecl bool jackbridge_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); | __cdecl bool jackbridge_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); | ||||
| __cdecl bool jackbridge_sem_init(void* sem) noexcept; | __cdecl bool jackbridge_sem_init(void* sem) noexcept; | ||||
| __cdecl bool jackbridge_sem_destroy(void* sem) noexcept; | |||||
| __cdecl void jackbridge_sem_destroy(void* sem) noexcept; | |||||
| __cdecl bool jackbridge_sem_post(void* sem) noexcept; | __cdecl bool jackbridge_sem_post(void* sem) noexcept; | ||||
| __cdecl bool jackbridge_sem_timedwait(void* sem, int secs) noexcept; | |||||
| __cdecl bool jackbridge_sem_timedwait(void* sem, uint secs) noexcept; | |||||
| __cdecl bool jackbridge_shm_is_valid(const void* shm) noexcept; | __cdecl bool jackbridge_shm_is_valid(const void* shm) noexcept; | ||||
| __cdecl void jackbridge_shm_init(void* shm) noexcept; | __cdecl void jackbridge_shm_init(void* shm) noexcept; | ||||
| @@ -19,54 +19,28 @@ | |||||
| #ifdef JACKBRIDGE_DUMMY | #ifdef JACKBRIDGE_DUMMY | ||||
| # include "CarlaUtils.hpp" | # include "CarlaUtils.hpp" | ||||
| #else | #else | ||||
| # include <ctime> | |||||
| # include <sys/time.h> | |||||
| # include <sys/types.h> | |||||
| # include <semaphore.h> | |||||
| # ifdef CARLA_OS_MAC | |||||
| extern "C" { | |||||
| # include "osx_sem_timedwait.c" | |||||
| } | |||||
| # endif | |||||
| # include "CarlaSemUtils.hpp" | |||||
| # include "CarlaShmUtils.hpp" | # include "CarlaShmUtils.hpp" | ||||
| #endif // ! JACKBRIDGE_DUMMY | #endif // ! JACKBRIDGE_DUMMY | ||||
| // ----------------------------------------------------------------------------- | // ----------------------------------------------------------------------------- | ||||
| // TODO - check noexcept on OSX | |||||
| bool jackbridge_sem_init(void* sem) noexcept | bool jackbridge_sem_init(void* sem) noexcept | ||||
| { | { | ||||
| #if defined(JACKBRIDGE_DUMMY) | #if defined(JACKBRIDGE_DUMMY) | ||||
| return false; | return false; | ||||
| #elif defined(CARLA_OS_MAC) | |||||
| static ulong sCounter = 0; | |||||
| ++sCounter; | |||||
| std::srand(static_cast<uint>(std::time(nullptr))); | |||||
| char strBuf[0xff+1]; | |||||
| carla_zeroChar(strBuf, 0xff+1); | |||||
| std::sprintf(strBuf, "carla-sem-%i-%lu", std::rand(), sCounter); | |||||
| sem_unlink(strBuf); | |||||
| sem_t* const sema = sem_open(strBuf, O_CREAT, O_RDWR, 0); | |||||
| std::memcpy(sem, &sema, sizeof(sem_t*)); | |||||
| return (sema != nullptr && sema != SEM_FAILED); | |||||
| #else | #else | ||||
| return (sem_init((sem_t*)sem, 1, 0) == 0); | |||||
| sem_t* const sema(carla_sem_create()); | |||||
| std::memcpy(sem, &sema, sizeof(sem_t*)); | |||||
| //std::memcpy(sem, sema, sizeof(sem_t*)); | |||||
| return (sema != nullptr); | |||||
| #endif | #endif | ||||
| } | } | ||||
| bool jackbridge_sem_destroy(void* sem) noexcept | |||||
| void jackbridge_sem_destroy(void* sem) noexcept | |||||
| { | { | ||||
| #if defined(JACKBRIDGE_DUMMY) | |||||
| return false; | |||||
| #elif defined(CARLA_OS_MAC) | |||||
| return (sem_close(*(sem_t**)sem) == 0); | |||||
| #else | |||||
| return (sem_destroy((sem_t*)sem) == 0); | |||||
| #ifndef JACKBRIDGE_DUMMY | |||||
| carla_sem_destroy((sem_t*)sem); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -75,46 +49,21 @@ bool jackbridge_sem_post(void* sem) noexcept | |||||
| #ifdef JACKBRIDGE_DUMMY | #ifdef JACKBRIDGE_DUMMY | ||||
| return false; | return false; | ||||
| #else | #else | ||||
| # ifdef CARLA_OS_MAC | |||||
| sem_t* const sema = *(sem_t**)sem; | |||||
| # else | |||||
| sem_t* const sema = (sem_t*)sem; | |||||
| # endif | |||||
| return (sem_post(sema) == 0); | |||||
| return carla_sem_post((sem_t*)sem); | |||||
| #endif | #endif | ||||
| } | } | ||||
| bool jackbridge_sem_timedwait(void* sem, int secs) noexcept | |||||
| bool jackbridge_sem_timedwait(void* sem, uint secs) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(secs > 0, false); | |||||
| #ifdef JACKBRIDGE_DUMMY | #ifdef JACKBRIDGE_DUMMY | ||||
| return false; | return false; | ||||
| #else | #else | ||||
| # ifdef CARLA_OS_MAC | |||||
| sem_t* const sema = *(sem_t**)sem; | |||||
| # else | |||||
| sem_t* const sema = (sem_t*)sem; | |||||
| # endif | |||||
| timespec timeout; | |||||
| # ifdef CARLA_OS_LINUX | |||||
| clock_gettime(CLOCK_REALTIME, &timeout); | |||||
| # else | |||||
| timeval now; | |||||
| gettimeofday(&now, nullptr); | |||||
| timeout.tv_sec = now.tv_sec; | |||||
| timeout.tv_nsec = now.tv_usec * 1000; | |||||
| # endif | |||||
| timeout.tv_sec += secs; | |||||
| try { | |||||
| return (sem_timedwait(sema, &timeout) == 0); | |||||
| } CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false); | |||||
| return carla_sem_timedwait((sem_t*)sem, secs); | |||||
| #endif | #endif | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------- | |||||
| bool jackbridge_shm_is_valid(const void* shm) noexcept | bool jackbridge_shm_is_valid(const void* shm) noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(shm != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(shm != nullptr, false); | ||||
| @@ -107,13 +107,13 @@ typedef int (__cdecl *jackbridgesym_remove_properties)(jack_client_t* client, j | |||||
| typedef bool (__cdecl *jackbridgesym_remove_all_properties)(jack_client_t* client); | typedef bool (__cdecl *jackbridgesym_remove_all_properties)(jack_client_t* client); | ||||
| typedef bool (__cdecl *jackbridgesym_set_property_change_callback)(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); | typedef bool (__cdecl *jackbridgesym_set_property_change_callback)(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); | ||||
| typedef bool (__cdecl *jackbridgesym_sem_init)(void* sem); | typedef bool (__cdecl *jackbridgesym_sem_init)(void* sem); | ||||
| typedef bool (__cdecl *jackbridgesym_sem_destroy)(void* sem); | |||||
| typedef void (__cdecl *jackbridgesym_sem_destroy)(void* sem); | |||||
| typedef bool (__cdecl *jackbridgesym_sem_post)(void* sem); | typedef bool (__cdecl *jackbridgesym_sem_post)(void* sem); | ||||
| typedef bool (__cdecl *jackbridgesym_sem_timedwait)(void* sem, int secs); | |||||
| typedef bool (__cdecl *jackbridgesym_shm_is_valid)(const void* shm); | |||||
| typedef void (__cdecl *jackbridgesym_shm_init)(void* shm); | |||||
| typedef void (__cdecl *jackbridgesym_shm_attach)(void* shm, const char* name); | |||||
| typedef void (__cdecl *jackbridgesym_shm_close)(void* shm); | |||||
| typedef bool (__cdecl *jackbridgesym_sem_timedwait)(void* sem, uint secs); | |||||
| typedef bool (__cdecl *jackbridgesym_shm_is_valid)(const void* shm); | |||||
| typedef void (__cdecl *jackbridgesym_shm_init)(void* shm); | |||||
| typedef void (__cdecl *jackbridgesym_shm_attach)(void* shm, const char* name); | |||||
| typedef void (__cdecl *jackbridgesym_shm_close)(void* shm); | |||||
| typedef void* (__cdecl *jackbridgesym_shm_map)(void* shm, size_t size); | typedef void* (__cdecl *jackbridgesym_shm_map)(void* shm, size_t size); | ||||
| // ----------------------------------------------------------------------------- | // ----------------------------------------------------------------------------- | ||||
| @@ -0,0 +1,123 @@ | |||||
| /* | |||||
| * Carla semaphore utils | |||||
| * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License as | |||||
| * published by the Free Software Foundation; either version 2 of | |||||
| * the License, or any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
| */ | |||||
| #ifndef CARLA_SEM_UTILS_HPP_INCLUDED | |||||
| #define CARLA_SEM_UTILS_HPP_INCLUDED | |||||
| #include "CarlaUtils.hpp" | |||||
| #include <ctime> | |||||
| #include <sys/time.h> | |||||
| #include <sys/types.h> | |||||
| #include <semaphore.h> | |||||
| #if defined(CARLA_OS_MAC) | |||||
| # include <fcntl.h> | |||||
| # include <unistd.h> | |||||
| extern "C" { | |||||
| # include "osx_sem_timedwait.c" | |||||
| }; | |||||
| #endif | |||||
| /* | |||||
| * Create a new semaphore. | |||||
| */ | |||||
| static inline | |||||
| sem_t* carla_sem_create() noexcept | |||||
| { | |||||
| #if defined(CARLA_OS_MAC) | |||||
| static ulong sCounter = 0; | |||||
| ++sCounter; | |||||
| std::srand(static_cast<uint>(std::time(nullptr))); | |||||
| char strBuf[0xff+1]; | |||||
| carla_zeroChar(strBuf, 0xff+1); | |||||
| std::snprintf(strBuf, 0xff, "carla-sem-%lu-%lu-%i", static_cast<ulong>(::getpid()), sCounter, std::rand()); | |||||
| ::sem_unlink(strBuf); | |||||
| return ::sem_open(strBuf, O_CREAT, O_RDWR, 0); | |||||
| #else | |||||
| sem_t* const sem((sem_t*)std::malloc(sizeof(sem_t))); | |||||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, nullptr); | |||||
| if (::sem_init(sem, 1, 0) != 0) | |||||
| { | |||||
| std::free(sem); | |||||
| return nullptr; | |||||
| } | |||||
| return sem; | |||||
| #endif | |||||
| } | |||||
| /* | |||||
| * Destroy a semaphore. | |||||
| */ | |||||
| static inline | |||||
| void carla_sem_destroy(sem_t* const sem) noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr,); | |||||
| #if defined(CARLA_OS_MAC) | |||||
| ::sem_close(sem); | |||||
| #else | |||||
| ::sem_destroy(sem); | |||||
| std::free(sem); | |||||
| #endif | |||||
| } | |||||
| /* | |||||
| * Post semaphore (unlock). | |||||
| */ | |||||
| static inline | |||||
| bool carla_sem_post(sem_t* const sem) noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | |||||
| return (::sem_post(sem) == 0); | |||||
| } | |||||
| /* | |||||
| * Wait for a semaphore (lock). | |||||
| */ | |||||
| static inline | |||||
| 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); | |||||
| timespec timeout; | |||||
| #ifdef CARLA_OS_LINUX | |||||
| ::clock_gettime(CLOCK_REALTIME, &timeout); | |||||
| #else | |||||
| timeval now; | |||||
| ::gettimeofday(&now, nullptr); | |||||
| timeout.tv_sec = now.tv_sec; | |||||
| timeout.tv_nsec = now.tv_usec * 1000; | |||||
| #endif | |||||
| timeout.tv_sec += secs; | |||||
| try { | |||||
| return (::sem_timedwait(sem, &timeout) == 0); | |||||
| } CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| #endif // CARLA_SEM_UTILS_HPP_INCLUDED | |||||
| @@ -125,6 +125,7 @@ shm_t carla_shm_attach(const char* const filename) noexcept | |||||
| #endif | #endif | ||||
| } | } | ||||
| catch(...) { | catch(...) { | ||||
| carla_safe_exception("carla_shm_attach", __FILE__, __LINE__); | |||||
| ret = gNullCarlaShm; | ret = gNullCarlaShm; | ||||
| } | } | ||||
| @@ -174,10 +175,10 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept | |||||
| try { | try { | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| const HANDLE map = ::CreateFileMapping(shm.shm, nullptr, PAGE_READWRITE, size, size, nullptr); | |||||
| const HANDLE map(:CreateFileMapping(shm.shm, nullptr, PAGE_READWRITE, size, size, nullptr)); | |||||
| CARLA_SAFE_ASSERT_RETURN(map != nullptr, nullptr); | CARLA_SAFE_ASSERT_RETURN(map != nullptr, nullptr); | ||||
| HANDLE ptr = ::MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size); | |||||
| const HANDLE ptr(::MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size)); | |||||
| if (ptr == nullptr) | if (ptr == nullptr) | ||||
| { | { | ||||
| @@ -191,7 +192,7 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept | |||||
| #else | #else | ||||
| if (shm.filename != nullptr) | if (shm.filename != nullptr) | ||||
| { | { | ||||
| const int ret = ::ftruncate(shm.fd, static_cast<off_t>(size)); | |||||
| const int ret(::ftruncate(shm.fd, static_cast<off_t>(size))); | |||||
| CARLA_SAFE_ASSERT_RETURN(ret == 0, nullptr); | CARLA_SAFE_ASSERT_RETURN(ret == 0, nullptr); | ||||
| } | } | ||||
| @@ -215,13 +216,13 @@ void carla_shm_unmap(shm_t& shm, void* const ptr, const std::size_t size) noexce | |||||
| try { | try { | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| const HANDLE map = shm.map; | |||||
| const HANDLE map(shm.map); | |||||
| shm.map = nullptr; | shm.map = nullptr; | ||||
| ::UnmapViewOfFile(ptr); | ::UnmapViewOfFile(ptr); | ||||
| ::CloseHandle(map); | ::CloseHandle(map); | ||||
| #else | #else | ||||
| const int ret = ::munmap(ptr, size); | |||||
| const int ret(::munmap(ptr, size)); | |||||
| CARLA_SAFE_ASSERT(ret == 0); | CARLA_SAFE_ASSERT(ret == 0); | ||||
| #endif | #endif | ||||
| } CARLA_SAFE_EXCEPTION("carla_shm_unmap"); | } CARLA_SAFE_EXCEPTION("carla_shm_unmap"); | ||||