Browse Source

Add Shm utilities, to be later used for plugin bridges

tags/1.9.4
falkTX 11 years ago
parent
commit
f1c3f7cd2a
1 changed files with 195 additions and 0 deletions
  1. +195
    -0
      source/utils/CarlaShmUtils.hpp

+ 195
- 0
source/utils/CarlaShmUtils.hpp View File

@@ -0,0 +1,195 @@
/*
* Carla shared memory utils
* Copyright (C) 2013 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 GPL.txt file
*/

#ifndef __CARLA_SHM_UTILS_HPP__
#define __CARLA_SHM_UTILS_HPP__

#include "CarlaUtils.hpp"

#ifdef CARLA_OS_WIN
# include <vector>
# include <windows.h>
struct map_t { HANDLE map; void* ptr; };
struct shm_t { HANDLE shm; std::vector<map_t> maps; };
#else
# include <fcntl.h>
# include <sys/mman.h>
typedef int shm_t;
#endif

// -------------------------------------------------
// shared memory calls

static inline
bool carla_is_shm_valid(shm_t shm)
{
#ifdef CARLA_OS_WIN
return (shm.shm != nullptr && shm.shm != INVALID_HANDLE_VALUE);
#else
return (shm >= 0);
#endif
}

static inline
void carla_shm_init(shm_t& shm)
{
#ifdef CARLA_OS_WIN
shm.shm = nullptr;
shm.maps.clear();
#else
shm = -1;
#endif
}

#ifdef CARLA_OS_WIN
static inline
shm_t carla_shm_attach_linux(const char* const name)
{
CARLA_ASSERT(name != nullptr);

char shmName[std::strlen(name)+10];
std::strcpy(shmName, "/dev/shm/");
std::strcat(shmName, name);

shm_t ret;
ret.shm = CreateFileA(shmName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

return ret;
}
#else
static inline
shm_t carla_shm_create(const char* const name)
{
CARLA_ASSERT(name != nullptr);

return shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
}

static inline
shm_t carla_shm_attach(const char* const name)
{
CARLA_ASSERT(name != nullptr);

return shm_open(name, O_RDWR, 0);
}
#endif

static inline
void carla_shm_close(shm_t& shm)
{
CARLA_ASSERT(carla_is_shm_valid(shm));

#ifdef CARLA_OS_WIN
CARLA_ASSERT(shm.maps.empty());

CloseHandle(shm.shm);
shm.shm = nullptr;
#else
close(shm);
shm = -1;
#endif
}

static inline
void* carla_shm_map(shm_t shm, const size_t size)
{
CARLA_ASSERT(carla_is_shm_valid(shm));
CARLA_ASSERT(size > 0);

#ifdef CARLA_OS_WIN
HANDLE map = CreateFileMapping(shm.shm, NULL, PAGE_READWRITE, size, size, NULL);

if (map == nullptr)
return nullptr;

HANDLE ptr = MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size);

if (ptr == nullptr)
return nullptr;

map_t newMap;
newMap.map = map;
newMap.ptr = ptr;

shm.maps.push_back(newMap);

return ptr;
#else
return mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0);
#endif
}

static inline
void carla_shm_unmap(const shm_t shm, void* const ptr, const size_t size)
{
CARLA_ASSERT(carla_is_shm_valid(shm));
CARLA_ASSERT(ptr != nullptr);
CARLA_ASSERT(size > 0);

#ifdef CARLA_OS_WIN
CARLA_ASSERT(! shm.maps.empty());

for (auto it = shm.maps.begin(); it != shm.maps.end(); ++it)
{
map_t map(*it);

if (map.ptr == ptr)
{
UnmapViewOfFile(ptr);
CloseHandle(map.map);

shm.maps.erase(it);
break;
}
}

CARLA_ASSERT(false);

return;

// unused
(void)size;
#else
munmap(ptr, size);
return;

// unused
(void)shm;
#endif
}

// -------------------------------------------------
// shared memory, templated calls

template<typename T>
static inline
void carla_shm_map(shm_t shm, T* value)
{
value = carla_shm_map(shm, sizeof(value));
}

template<typename T>
static inline
void carla_shm_unmap(const shm_t shm, T* value)
{
carla_shm_unmap(shm, value, sizeof(value));
value = nullptr;
}

// -------------------------------------------------

#endif // __CARLA_SHM_UTILS_HPP__

Loading…
Cancel
Save