| @@ -162,18 +162,18 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> { | |||
| setRingBuffer(nullptr, false); | |||
| } | |||
| bool postClient() noexcept | |||
| void postClient() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | |||
| return jackbridge_sem_post(&data->sem.client); | |||
| jackbridge_sem_post(&data->sem.client); | |||
| } | |||
| bool waitForServer(const uint secs, bool* const timedOut) noexcept | |||
| bool waitForServer(const uint secs) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
| return jackbridge_sem_timedwait(&data->sem.server, secs, timedOut); | |||
| return jackbridge_sem_timedwait(&data->sem.server, secs); | |||
| } | |||
| PluginBridgeRtClientOpcode readOpcode() noexcept | |||
| @@ -1203,18 +1203,20 @@ public: | |||
| protected: | |||
| void run() override | |||
| { | |||
| bool timedOut, quitReceived = false; | |||
| bool timedOut = false; | |||
| bool quitReceived = false; | |||
| for (; ! shouldThreadExit();) | |||
| { | |||
| if (! fShmRtClientControl.waitForServer(5, &timedOut)) | |||
| if (! fShmRtClientControl.waitForServer(5)) | |||
| { | |||
| /* | |||
| * As a special case we ignore timeouts for plugin bridges. | |||
| * Some big Windows plugins (Kontakt, FL Studio VST) can time out when initializing or doing UI stuff. | |||
| * If any other error happens the plugin bridge is stopped. | |||
| */ | |||
| if (timedOut) continue; | |||
| // Give engine 1 more change to catch up. | |||
| if (! timedOut) | |||
| { | |||
| carla_stderr2("Bridge timed-out, giving it one more chance"); | |||
| timedOut = true; | |||
| continue; | |||
| } | |||
| carla_stderr2("Bridge timed-out, final post..."); | |||
| fShmRtClientControl.postClient(); | |||
| @@ -1223,6 +1225,8 @@ protected: | |||
| break; | |||
| } | |||
| timedOut = false; | |||
| for (; fShmRtClientControl.isDataAvailableForReading();) | |||
| { | |||
| const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode()); | |||
| @@ -1501,8 +1505,7 @@ protected: | |||
| } | |||
| } | |||
| if (! fShmRtClientControl.postClient()) | |||
| carla_stderr2("Could not post to client rt semaphore"); | |||
| fShmRtClientControl.postClient(); | |||
| } | |||
| callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr); | |||
| @@ -50,14 +50,14 @@ struct BridgeAudioPool { | |||
| CarlaString filename; | |||
| std::size_t size; | |||
| float* data; | |||
| shm_t shm; | |||
| carla_shm_t shm; | |||
| BridgeAudioPool() noexcept | |||
| : filename(), | |||
| size(0), | |||
| data(nullptr) | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| , shm(shm_t_INIT) {} | |||
| , shm(carla_shm_t_INIT) {} | |||
| #else | |||
| { | |||
| carla_shm_init(shm); | |||
| @@ -131,14 +131,14 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> { | |||
| BridgeRtClientData* data; | |||
| CarlaString filename; | |||
| bool needsSemDestroy; | |||
| shm_t shm; | |||
| carla_shm_t shm; | |||
| BridgeRtClientControl() | |||
| : data(nullptr), | |||
| filename(), | |||
| needsSemDestroy(false) | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| , shm(shm_t_INIT) {} | |||
| , shm(carla_shm_t_INIT) {} | |||
| #else | |||
| { | |||
| carla_shm_init(shm); | |||
| @@ -241,13 +241,13 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> { | |||
| setRingBuffer(nullptr, false); | |||
| } | |||
| bool waitForClient(const uint secs, bool* const timedOut) noexcept | |||
| bool waitForClient(const uint secs) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
| jackbridge_sem_post(&data->sem.server); | |||
| return jackbridge_sem_timedwait(&data->sem.client, secs, timedOut); | |||
| return jackbridge_sem_timedwait(&data->sem.client, secs); | |||
| } | |||
| void writeOpcode(const PluginBridgeRtClientOpcode opcode) noexcept | |||
| @@ -264,14 +264,14 @@ struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> | |||
| BridgeNonRtClientData* data; | |||
| CarlaString filename; | |||
| CarlaMutex mutex; | |||
| shm_t shm; | |||
| carla_shm_t shm; | |||
| BridgeNonRtClientControl() noexcept | |||
| : data(nullptr), | |||
| filename(), | |||
| mutex() | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| , shm(shm_t_INIT) {} | |||
| , shm(carla_shm_t_INIT) {} | |||
| #else | |||
| { | |||
| carla_shm_init(shm); | |||
| @@ -379,13 +379,13 @@ struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> | |||
| struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> { | |||
| BridgeNonRtServerData* data; | |||
| CarlaString filename; | |||
| shm_t shm; | |||
| carla_shm_t shm; | |||
| BridgeNonRtServerControl() noexcept | |||
| : data(nullptr), | |||
| filename() | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| , shm(shm_t_INIT) {} | |||
| , shm(carla_shm_t_INIT) {} | |||
| #else | |||
| { | |||
| carla_shm_init(shm); | |||
| @@ -2655,18 +2655,11 @@ private: | |||
| CARLA_SAFE_ASSERT_RETURN(! fTimedOut,); | |||
| CARLA_SAFE_ASSERT_RETURN(! fTimedError,); | |||
| if (fShmRtClientControl.waitForClient(secs, &fTimedOut)) | |||
| if (fShmRtClientControl.waitForClient(secs)) | |||
| return; | |||
| if (fTimedOut) | |||
| { | |||
| carla_stderr("waitForClient(%s) timeout here", action); | |||
| } | |||
| else | |||
| { | |||
| fTimedError = true; | |||
| carla_stderr("waitForClient(%s) error while waiting", action); | |||
| } | |||
| fTimedOut = true; | |||
| carla_stderr("waitForClient(%s) timeout here", action); | |||
| } | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridge) | |||
| @@ -392,13 +392,13 @@ __cdecl bool jackbridge_set_property_change_callback(jack_client_t* client, Jack | |||
| __cdecl bool jackbridge_sem_init(void* sem) noexcept; | |||
| __cdecl void jackbridge_sem_destroy(void* sem) noexcept; | |||
| __cdecl bool jackbridge_sem_post(void* sem) noexcept; | |||
| __cdecl bool jackbridge_sem_timedwait(void* sem, uint secs, bool* timedOut) noexcept; | |||
| __cdecl void jackbridge_sem_post(void* sem) noexcept; | |||
| __cdecl bool jackbridge_sem_timedwait(void* sem, uint secs) noexcept; | |||
| __cdecl bool jackbridge_shm_is_valid(const void* shm) noexcept; | |||
| __cdecl void jackbridge_shm_init(void* shm) noexcept; | |||
| __cdecl void jackbridge_shm_attach(void* shm, const char* name) noexcept; | |||
| __cdecl void jackbridge_shm_close(void* shm) noexcept; | |||
| __cdecl void* jackbridge_shm_map(void* shm, size_t size) noexcept; | |||
| __cdecl void* jackbridge_shm_map(void* shm, uint64_t size) noexcept; | |||
| #endif // JACKBRIDGE_HPP_INCLUDED | |||
| @@ -19,7 +19,6 @@ | |||
| #ifdef JACKBRIDGE_DUMMY | |||
| # include "CarlaUtils.hpp" | |||
| #else | |||
| # include <cerrno> | |||
| # include "CarlaSemUtils.hpp" | |||
| # include "CarlaShmUtils.hpp" | |||
| #endif // ! JACKBRIDGE_DUMMY | |||
| @@ -28,51 +27,39 @@ | |||
| bool jackbridge_sem_init(void* sem) noexcept | |||
| { | |||
| #ifdef JACKBRIDGE_DUMMY | |||
| return false; | |||
| #else | |||
| sem_t* const sema(carla_sem_create()); | |||
| CARLA_SAFE_ASSERT_RETURN(sema != nullptr, false); | |||
| # ifdef CARLA_OS_MAC | |||
| std::memcpy(sem, &sema, sizeof(sem_t*)); | |||
| # else | |||
| std::memcpy(sem, sema, sizeof(sem_t)); | |||
| # endif | |||
| return (sema != nullptr); | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| return carla_sem_create2(*(carla_sem_t*)sem); | |||
| #endif | |||
| } | |||
| void jackbridge_sem_destroy(void* sem) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr,); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| carla_sem_destroy((sem_t*)sem); | |||
| carla_sem_destroy2(*(carla_sem_t*)sem); | |||
| #endif | |||
| } | |||
| bool jackbridge_sem_post(void* sem) noexcept | |||
| void jackbridge_sem_post(void* sem) noexcept | |||
| { | |||
| #ifdef JACKBRIDGE_DUMMY | |||
| return false; | |||
| #else | |||
| return carla_sem_post((sem_t*)sem); | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr,); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| carla_sem_post(*(carla_sem_t*)sem); | |||
| #endif | |||
| } | |||
| bool jackbridge_sem_timedwait(void* sem, uint secs, bool* timedOut) noexcept | |||
| bool jackbridge_sem_timedwait(void* sem, uint secs) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(timedOut != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | |||
| #ifdef JACKBRIDGE_DUMMY | |||
| return false; | |||
| #else | |||
| if (carla_sem_timedwait((sem_t*)sem, secs)) | |||
| { | |||
| *timedOut = false; | |||
| return true; | |||
| } | |||
| *timedOut = (errno == ETIMEDOUT); | |||
| return false; | |||
| return carla_sem_timedwait(*(carla_sem_t*)sem, secs); | |||
| #endif | |||
| } | |||
| @@ -85,7 +72,7 @@ bool jackbridge_shm_is_valid(const void* shm) noexcept | |||
| #ifdef JACKBRIDGE_DUMMY | |||
| return false; | |||
| #else | |||
| return carla_is_shm_valid(*(const shm_t*)shm); | |||
| return carla_is_shm_valid(*(const carla_shm_t*)shm); | |||
| #endif | |||
| } | |||
| @@ -94,7 +81,7 @@ void jackbridge_shm_init(void* shm) noexcept | |||
| CARLA_SAFE_ASSERT_RETURN(shm != nullptr,); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| carla_shm_init(*(shm_t*)shm); | |||
| carla_shm_init(*(carla_shm_t*)shm); | |||
| #endif | |||
| } | |||
| @@ -103,7 +90,7 @@ void jackbridge_shm_attach(void* shm, const char* name) noexcept | |||
| CARLA_SAFE_ASSERT_RETURN(shm != nullptr,); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| *(shm_t*)shm = carla_shm_attach(name); | |||
| *(carla_shm_t*)shm = carla_shm_attach(name); | |||
| #endif | |||
| } | |||
| @@ -112,18 +99,18 @@ void jackbridge_shm_close(void* shm) noexcept | |||
| CARLA_SAFE_ASSERT_RETURN(shm != nullptr,); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| carla_shm_close(*(shm_t*)shm); | |||
| carla_shm_close(*(carla_shm_t*)shm); | |||
| #endif | |||
| } | |||
| void* jackbridge_shm_map(void* shm, size_t size) noexcept | |||
| void* jackbridge_shm_map(void* shm, uint64_t size) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(shm != nullptr, nullptr); | |||
| #ifdef JACKBRIDGE_DUMMY | |||
| return nullptr; | |||
| #else | |||
| return carla_shm_map(*(shm_t*)shm, size); | |||
| return carla_shm_map(*(carla_shm_t*)shm, size); | |||
| #endif | |||
| } | |||
| @@ -535,14 +535,14 @@ void jackbridge_sem_destroy(void* sem) noexcept | |||
| getBridgeInstance().sem_destroy_ptr(sem); | |||
| } | |||
| bool jackbridge_sem_post(void* sem) noexcept | |||
| void jackbridge_sem_post(void* sem) noexcept | |||
| { | |||
| return getBridgeInstance().sem_post_ptr(sem); | |||
| getBridgeInstance().sem_post_ptr(sem); | |||
| } | |||
| bool jackbridge_sem_timedwait(void* sem, uint secs, bool* timedOut) noexcept | |||
| bool jackbridge_sem_timedwait(void* sem, uint secs) noexcept | |||
| { | |||
| return getBridgeInstance().sem_timedwait_ptr(sem, secs, timedOut); | |||
| return getBridgeInstance().sem_timedwait_ptr(sem, secs); | |||
| } | |||
| bool jackbridge_shm_is_valid(const void* shm) noexcept | |||
| @@ -565,7 +565,7 @@ void jackbridge_shm_close(void* shm) noexcept | |||
| return getBridgeInstance().shm_close_ptr(shm); | |||
| } | |||
| void* jackbridge_shm_map(void* shm, size_t size) noexcept | |||
| void* jackbridge_shm_map(void* shm, uint64_t size) noexcept | |||
| { | |||
| return getBridgeInstance().shm_map_ptr(shm, size); | |||
| } | |||
| @@ -110,13 +110,13 @@ typedef bool (__cdecl *jackbridgesym_remove_all_properties)(jack_client_t* clien | |||
| 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 void (__cdecl *jackbridgesym_sem_destroy)(void* sem); | |||
| typedef bool (__cdecl *jackbridgesym_sem_post)(void* sem); | |||
| typedef bool (__cdecl *jackbridgesym_sem_timedwait)(void* sem, uint secs, bool* timedOut); | |||
| typedef void (__cdecl *jackbridgesym_sem_post)(void* sem); | |||
| 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, uint64_t size); | |||
| } // extern "C" | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla semaphore utils | |||
| * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2013-2015 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 | |||
| @@ -23,110 +23,95 @@ | |||
| #include <ctime> | |||
| #ifdef CARLA_OS_WIN | |||
| struct sem_t { HANDLE handle; }; | |||
| struct carla_sem_t { HANDLE handle; }; | |||
| #elif defined(CARLA_OS_MAC) | |||
| // TODO | |||
| struct carla_sem_t { char dummy; }; | |||
| #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" | |||
| }; | |||
| # endif | |||
| struct carla_sem_t { sem_t sem; }; | |||
| #endif | |||
| /* | |||
| * Create a new semaphore. | |||
| * Create a new semaphore, pre-allocated version. | |||
| */ | |||
| static inline | |||
| sem_t* carla_sem_create() noexcept | |||
| bool carla_sem_create2(carla_sem_t& sem) noexcept | |||
| { | |||
| #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); | |||
| sem.handle = ::CreateSemaphore(&sa, 0, 1, nullptr); | |||
| return sem; | |||
| return (sem.handle != INVALID_HANDLE_VALUE); | |||
| #elif defined(CARLA_OS_MAC) | |||
| static ulong sCounter = 0; | |||
| if (++sCounter == 1) | |||
| std::srand(static_cast<uint>(std::time(nullptr))); | |||
| char strBuf[0xff+1]; | |||
| carla_zeroChars(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); | |||
| return false; // TODO | |||
| #else | |||
| sem_t sem; | |||
| if (::sem_init(&sem, 1, 0) != 0) | |||
| return nullptr; | |||
| return (::sem_init(&sem.sem, 1, 0) == 0); | |||
| #endif | |||
| } | |||
| // can't return temporary variable, so allocate a new one | |||
| if (sem_t* const sem2 = (sem_t*)std::malloc(sizeof(sem_t))) | |||
| /* | |||
| * Create a new semaphore. | |||
| */ | |||
| static inline | |||
| carla_sem_t* carla_sem_create() noexcept | |||
| { | |||
| if (carla_sem_t* const sem = (carla_sem_t*)std::malloc(sizeof(carla_sem_t))) | |||
| { | |||
| std::memcpy(sem2, &sem, sizeof(sem_t)); | |||
| return sem2; | |||
| if (carla_sem_create2(*sem)) | |||
| return sem; | |||
| std::free(sem); | |||
| } | |||
| ::sem_destroy(&sem); | |||
| return nullptr; | |||
| #endif | |||
| } | |||
| /* | |||
| * Destroy a semaphore. | |||
| * Destroy a semaphore, pre-allocated version. | |||
| */ | |||
| static inline | |||
| void carla_sem_destroy(sem_t* const sem) noexcept | |||
| void carla_sem_destroy2(carla_sem_t& sem) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr,); | |||
| #if defined(CARLA_OS_WIN) | |||
| ::CloseHandle(sem->handle); | |||
| std::free(sem); | |||
| ::CloseHandle(sem.handle); | |||
| #elif defined(CARLA_OS_MAC) | |||
| ::sem_close(sem); | |||
| // TODO | |||
| #else | |||
| // we can't call "sem_destroy(sem)" directly because it will free memory which we allocated during carla_sem_create() | |||
| // so we create a temp variable, free our memory, and finally pass the temp variable to sem_destroy() | |||
| // temp var | |||
| sem_t sem2; | |||
| std::memcpy(&sem2, sem, sizeof(sem_t)); | |||
| ::sem_destroy(&sem.sem); | |||
| #endif | |||
| } | |||
| // destroy semaphore | |||
| ::sem_destroy(&sem2); | |||
| /* | |||
| * Destroy a semaphore. | |||
| */ | |||
| static inline | |||
| void carla_sem_destroy(carla_sem_t* const sem) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr,); | |||
| // free memory allocated in carla_sem_create() | |||
| // FIXME | |||
| //std::free(sem); | |||
| #endif | |||
| carla_sem_destroy2(*sem); | |||
| std::free(sem); | |||
| } | |||
| /* | |||
| * Post semaphore (unlock). | |||
| */ | |||
| static inline | |||
| bool carla_sem_post(sem_t* const sem) noexcept | |||
| void carla_sem_post(carla_sem_t& sem) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false); | |||
| #ifdef CARLA_OS_WIN | |||
| return (::ReleaseSemaphore(sem->handle, 1, nullptr) != FALSE); | |||
| ::ReleaseSemaphore(sem.handle, 1, nullptr); | |||
| #elif defined(CARLA_OS_MAC) | |||
| // TODO | |||
| #else | |||
| return (::sem_post(sem) == 0); | |||
| ::sem_post(&sem.sem); | |||
| #endif | |||
| } | |||
| @@ -134,25 +119,14 @@ bool carla_sem_post(sem_t* const sem) noexcept | |||
| * Wait for a semaphore (lock). | |||
| */ | |||
| static inline | |||
| bool carla_sem_timedwait(sem_t* const sem, const uint secs) noexcept | |||
| bool carla_sem_timedwait(carla_sem_t& 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; | |||
| } | |||
| return (::WaitForSingleObject(sem.handle, secs*1000) == WAIT_OBJECT_0); | |||
| #elif defined(CARLA_OS_MAC) | |||
| // TODO | |||
| #else | |||
| timespec timeout; | |||
| # ifdef CARLA_OS_LINUX | |||
| @@ -166,7 +140,7 @@ bool carla_sem_timedwait(sem_t* const sem, const uint secs) noexcept | |||
| timeout.tv_sec += static_cast<time_t>(secs); | |||
| try { | |||
| return (::sem_timedwait(sem, &timeout) == 0); | |||
| return (::sem_timedwait(&sem.sem, &timeout) == 0); | |||
| } CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false); | |||
| #endif | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla shared memory utils | |||
| * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2013-2015 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 | |||
| @@ -21,14 +21,16 @@ | |||
| #include "CarlaUtils.hpp" | |||
| #ifdef CARLA_OS_WIN | |||
| struct shm_t { HANDLE map; bool isServer; const char* filename; }; | |||
| # define shm_t_INIT { INVALID_HANDLE_VALUE, true, nullptr } | |||
| struct carla_shm_t { HANDLE map; bool isServer; const char* filename; }; | |||
| # define carla_shm_t_INIT { INVALID_HANDLE_VALUE, true, nullptr } | |||
| #else | |||
| # include <cerrno> | |||
| # ifndef __WINE__ | |||
| # include <cerrno> | |||
| # endif | |||
| # include <fcntl.h> | |||
| # include <sys/mman.h> | |||
| struct shm_t { int fd; const char* filename; std::size_t size; }; | |||
| # define shm_t_INIT { -1, nullptr, 0 } | |||
| struct carla_shm_t { int fd; const char* filename; std::size_t size; }; | |||
| # define carla_shm_t_INIT { -1, nullptr, 0 } | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -37,13 +39,13 @@ struct shm_t { int fd; const char* filename; std::size_t size; }; | |||
| /* | |||
| * Null object returned when a shared memory operation fails. | |||
| */ | |||
| static const shm_t gNullCarlaShm = shm_t_INIT; | |||
| static const carla_shm_t gNullCarlaShm = carla_shm_t_INIT; | |||
| /* | |||
| * Check if a shared memory object is valid. | |||
| */ | |||
| static inline | |||
| bool carla_is_shm_valid(const shm_t& shm) noexcept | |||
| bool carla_is_shm_valid(const carla_shm_t& shm) noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| return (shm.filename != nullptr); | |||
| @@ -56,7 +58,7 @@ bool carla_is_shm_valid(const shm_t& shm) noexcept | |||
| * Initialize a shared memory object to an invalid state. | |||
| */ | |||
| static inline | |||
| void carla_shm_init(shm_t& shm) noexcept | |||
| void carla_shm_init(carla_shm_t& shm) noexcept | |||
| { | |||
| shm = gNullCarlaShm; | |||
| } | |||
| @@ -66,11 +68,11 @@ void carla_shm_init(shm_t& shm) noexcept | |||
| * Returns an invalid object if the operation failed or the filename already exists. | |||
| */ | |||
| static inline | |||
| shm_t carla_shm_create(const char* const filename) noexcept | |||
| carla_shm_t carla_shm_create(const char* const filename) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', gNullCarlaShm); | |||
| shm_t ret; | |||
| carla_shm_t ret; | |||
| #ifdef CARLA_OS_WIN | |||
| ret.map = INVALID_HANDLE_VALUE; | |||
| @@ -98,11 +100,11 @@ shm_t carla_shm_create(const char* const filename) noexcept | |||
| * Attach to an existing shared memory object. | |||
| */ | |||
| static inline | |||
| shm_t carla_shm_attach(const char* const filename) noexcept | |||
| carla_shm_t carla_shm_attach(const char* const filename) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', gNullCarlaShm); | |||
| shm_t ret; | |||
| carla_shm_t ret; | |||
| #ifdef CARLA_OS_WIN | |||
| ret.map = INVALID_HANDLE_VALUE; | |||
| @@ -123,7 +125,7 @@ shm_t carla_shm_attach(const char* const filename) noexcept | |||
| * Close a shared memory object and invalidate it. | |||
| */ | |||
| static inline | |||
| void carla_shm_close(shm_t& shm) noexcept | |||
| void carla_shm_close(carla_shm_t& shm) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),); | |||
| #ifdef CARLA_OS_WIN | |||
| @@ -153,7 +155,7 @@ void carla_shm_close(shm_t& shm) noexcept | |||
| * @note One shared memory object can only have one mapping at a time. | |||
| */ | |||
| static inline | |||
| void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept | |||
| void* carla_shm_map(carla_shm_t& shm, const std::size_t size) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm), nullptr); | |||
| CARLA_SAFE_ASSERT_RETURN(size > 0, nullptr); | |||
| @@ -210,7 +212,7 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept | |||
| * Unmap a shared memory object address. | |||
| */ | |||
| static inline | |||
| void carla_shm_unmap(shm_t& shm, void* const ptr) noexcept | |||
| void carla_shm_unmap(carla_shm_t& shm, void* const ptr) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),); | |||
| CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,); | |||
| @@ -237,6 +239,7 @@ void carla_shm_unmap(shm_t& shm, void* const ptr) noexcept | |||
| } CARLA_SAFE_EXCEPTION("carla_shm_unmap"); | |||
| } | |||
| #ifndef __WINE__ | |||
| // ----------------------------------------------------------------------- | |||
| // advanced calls | |||
| @@ -245,7 +248,7 @@ void carla_shm_unmap(shm_t& shm, void* const ptr) noexcept | |||
| * Will keep trying until a free random filename is obtained. | |||
| */ | |||
| static inline | |||
| shm_t carla_shm_create_temp(char* const fileBase) noexcept | |||
| carla_shm_t carla_shm_create_temp(char* const fileBase) noexcept | |||
| { | |||
| // check if the fileBase name is valid | |||
| CARLA_SAFE_ASSERT_RETURN(fileBase != nullptr, gNullCarlaShm); | |||
| @@ -269,7 +272,7 @@ shm_t carla_shm_create_temp(char* const fileBase) noexcept | |||
| fileBase[c] = charSet[std::rand() % charSetLen]; | |||
| // (try to) create new shm for this filename | |||
| const shm_t shm = carla_shm_create(fileBase); | |||
| const carla_shm_t shm = carla_shm_create(fileBase); | |||
| // all ok! | |||
| if (carla_is_shm_valid(shm)) | |||
| @@ -298,7 +301,7 @@ shm_t carla_shm_create_temp(char* const fileBase) noexcept | |||
| */ | |||
| template<typename T> | |||
| static inline | |||
| T* carla_shm_map(shm_t& shm) noexcept | |||
| T* carla_shm_map(carla_shm_t& shm) noexcept | |||
| { | |||
| return (T*)carla_shm_map(shm, sizeof(T)); | |||
| } | |||
| @@ -308,7 +311,7 @@ T* carla_shm_map(shm_t& shm) noexcept | |||
| */ | |||
| template<typename T> | |||
| static inline | |||
| bool carla_shm_map(shm_t& shm, T*& value) noexcept | |||
| bool carla_shm_map(carla_shm_t& shm, T*& value) noexcept | |||
| { | |||
| value = (T*)carla_shm_map(shm, sizeof(T)); | |||
| return (value != nullptr); | |||
| @@ -316,4 +319,6 @@ bool carla_shm_map(shm_t& shm, T*& value) noexcept | |||
| // ----------------------------------------------------------------------- | |||
| #endif // __WINE__ | |||
| #endif // CARLA_SHM_UTILS_HPP_INCLUDED | |||