30#include <boost/interprocess/managed_shared_memory.hpp>
31#include <boost/interprocess/sync/interprocess_condition.hpp>
32#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
33#include <boost/interprocess/sync/sharable_lock.hpp>
41#include <ArmarXCore/interface/core/SharedMemory.h>
46 boost::interprocess::scoped_lock<boost::interprocess::interprocess_upgradable_mutex>;
49 boost::interprocess::sharable_lock<boost::interprocess::interprocess_upgradable_mutex>;
89 template <
class MemoryObject,
class MemoryObjectMetaInfo = MetaInfoSizeBase>
93 class Wrapper :
public MemoryObjectMetaInfo
100 Wrapper(
const MemoryObjectMetaInfo& source) : MemoryObjectMetaInfo(source)
114 typename MemoryObjectMetaInfo::PointerType info)
118 if (info->capacity <= 0)
121 newMemoryName,
"Invalic memory capacity. Capacity must be >0");
124 this->memoryName = newMemoryName;
125 auto env_c_str = getenv(
"USER");
126 std::string userName = env_c_str ? env_c_str :
"";
129 if (!userName.empty())
131 this->memoryName += userName;
137 boost::interprocess::shared_memory_object::remove(this->memoryName.c_str());
142 std::size_t shmSize = info->capacity +
sizeof(MemoryObjectMetaInfo) +
143 sizeof(boost::interprocess::interprocess_mutex) +
144 sizeof(boost::interprocess::interprocess_condition) + 1024;
148 sharedMemorySegment =
new boost::interprocess::managed_shared_memory(
149 boost::interprocess::open_or_create, memoryName.c_str(), shmSize);
151 catch (std::exception& e)
155 "Error creating shared memory segment. Still a consumer running?\nReason: ")
160 sharedMemorySegment->destroy<
Wrapper>(
"Info");
161 this->info = sharedMemorySegment->find_or_construct<
Wrapper>(
"Info")();
166 memoryName,
"Error constructing shared memory segment.");
172 sharedMemorySegment->destroy<boost::interprocess::interprocess_upgradable_mutex>(
176 ->find_or_construct<boost::interprocess::interprocess_upgradable_mutex>(
182 memoryName,
"Error constructing SharedMutex in shared memory segment.");
185 sharedMemorySegment->destroy<boost::interprocess::interprocess_condition>(
188 sharedMemorySegment->find_or_construct<boost::interprocess::interprocess_condition>(
189 "CondSizeChanged")();
191 if (!condSizeChanged)
194 memoryName,
"Error constructing condition variable in shared memory segment.");
198 sharedMemorySegment->destroy<MemoryObject>(
"Data");
200 sharedMemorySegment->find_or_construct<MemoryObject>(
"Data")[info->capacity]();
205 memoryName,
"Error constructing data in shared memory segment.");
218 boost::interprocess::shared_memory_object::remove(memoryName.c_str());
232 MemoryObjectMetaInfo*
239 setMetaInfo(
const typename MemoryObjectMetaInfo::PointerType& info,
bool threadSafe =
false)
253 if (info->capacity != this->info->capacity)
258 "capacity is not equal - changing not implemented yet. Old capacity: ")
259 << this->info->capacity <<
" new capacity: " << info->capacity;
261 else if (info->size > this->info->capacity)
264 memoryName,
"object size exceeds capacity: size: ")
265 << info->size <<
" capacity: " << this->info->capacity;
268 bool sizeChanged = (this->info->size != info->size);
272 condSizeChanged->notify_all();
298 return info->capacity;
357 memoryMutex->unlock();
365 std::shared_ptr<SharedMemoryProvider<MemoryObject, MemoryObjectMetaInfo>>;
371 std::string memoryName;
376 boost::interprocess::managed_shared_memory* sharedMemorySegment;
381 mutable boost::interprocess::interprocess_upgradable_mutex* memoryMutex;
386 boost::interprocess::interprocess_condition* condSizeChanged;
393 MemoryObjectMetaInfo* info;
Wrapper(const MemoryObjectMetaInfo &source)
MemoryObject * getMemory() const
Retrieve pointer to shared memory.
std::shared_ptr< SharedMemoryProvider< MemoryObject, MemoryObjectMetaInfo > > pointer_type
Pointer type for convenience.
SharedMemoryProvider(const std::string &newMemoryName, typename MemoryObjectMetaInfo::PointerType info)
Creates a shared memory provider.
int getCapacity() const
Retrieve size of usable shared memory.
~SharedMemoryProvider()
Destructs the shared memory provider.
SharedMemoryScopedReadLockPtr getScopedReadLock() const
Retrieve scoped lock to the shared memory for reading.
SharedMemoryScopedWriteLockPtr getScopedWriteLock() const
Retrieve scoped lock to the shared memory for writing.
int getSize() const
Retrieve size of actual used shared memory.
void unlock()
Unlock shared memory after writing.
void lock()
Lock shared memory for writing.
void setMetaInfo(const typename MemoryObjectMetaInfo::PointerType &info, bool threadSafe=false)
MemoryObjectMetaInfo * getMetaInfo() const
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< SharedMemoryScopedWriteLock > SharedMemoryScopedWriteLockPtr
std::shared_ptr< SharedMemoryScopedReadLock > SharedMemoryScopedReadLockPtr
boost::interprocess::sharable_lock< boost::interprocess::interprocess_upgradable_mutex > SharedMemoryScopedReadLock
boost::interprocess::scoped_lock< boost::interprocess::interprocess_upgradable_mutex > SharedMemoryScopedWriteLock