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