16 explicit IpcNamedMutex(boost::interprocess::named_mutex& mx) : _mx(mx) {}
18 template<
typename Duration>
20 bool try_lock_for(
const Duration& dur) {
21 auto abs_time = boost::posix_time::microsec_clock::universal_time();
22 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
23 auto bmillis = boost::posix_time::milliseconds(millis);
25 return _mx.timed_lock(abs_time);
28 template<
typename Duration>
30 bool try_lock_until(
const Duration& abs_time) {
31 return _mx.timed_lock(abs_time);
34 void lock() { _mx.lock(); }
36 void unlock() { _mx.unlock(); }
39 bool try_lock() {
return _mx.try_lock(); }
42 boost::interprocess::named_mutex& _mx;
47 SharedDummyBackend::SharedMemoryManager::SharedMemoryManager(
48 SharedDummyBackend& sharedDummyBackend_, std::size_t instanceIdHash,
const std::string& mapFileName)
49 : sharedDummyBackend(sharedDummyBackend_), name(Utilities::
createShmName(instanceIdHash, mapFileName,
getUserName())),
50 segment(boost::interprocess::open_or_create, name.c_str(), getRequiredMemoryWithOverhead()),
51 sharedMemoryIntAllocator(segment.get_segment_manager()),
52 interprocessMutex(boost::interprocess::open_or_create, name.c_str()) {
56 IpcNamedMutex proxy(interprocessMutex);
57 std::unique_lock<IpcNamedMutex> lock(proxy, std::defer_lock);
58 bool ok = lock.try_lock_for(std::chrono::milliseconds(2000));
60 std::cerr <<
"SharedDummyBackend: stale lock detected, removing mutex... " << std::endl;
63 boost::interprocess::named_mutex::remove(name.c_str());
64 interprocessMutex.~named_mutex();
65 new(&interprocessMutex) boost::interprocess::named_mutex(boost::interprocess::open_or_create, name.c_str());
70 pidSet = findOrConstructVector(SHARED_MEMORY_PID_SET_NAME, 0);
73 bool reInitRequired = checkPidSetConsistency();
82 requiredVersion = segment.find_or_construct<
unsigned>(SHARED_MEMORY_REQUIRED_VERSION_NAME)(0);
86 if(pidSet->size() >= SHARED_MEMORY_N_MAX_MEMBER) {
87 std::string errMsg{
"Maximum number of accessing members reached."};
90 InterruptDispatcherInterface::cleanupShm(segment, pidSet);
92 pidSet->emplace_back(
static_cast<int32_t
>(
getOwnPID()));
94 this->intDispatcherIf = boost::movelib::unique_ptr<InterruptDispatcherInterface>(
95 new InterruptDispatcherInterface(sharedDummyBackend, segment, interprocessMutex));
98 SharedDummyBackend::SharedMemoryManager::~SharedMemoryManager() {
100 intDispatcherIf.reset();
108 std::lock_guard<boost::interprocess::named_mutex> lock(interprocessMutex);
111 checkPidSetConsistency();
113 auto ownPid =
static_cast<int32_t
>(
getOwnPID());
114 for(
auto it = pidSet->begin(); it != pidSet->end();) {
116 it = pidSet->erase(it);
122 pidSetSize = pidSet->size();
124 catch(boost::interprocess::interprocess_exception&) {
131 if(pidSetSize == 0) {
132 boost::interprocess::shared_memory_object::remove(name.c_str());
133 boost::interprocess::named_mutex::remove(name.c_str());
139 const std::string& objName,
const size_t size) {
141 segment.find_or_construct<
SharedMemoryVector>(objName.c_str())(size, 0, sharedMemoryIntAllocator);
146 size_t SharedDummyBackend::SharedMemoryManager::getRequiredMemoryWithOverhead() {
149 return SHARED_MEMORY_OVERHEAD_PER_VECTOR * sharedDummyBackend._barSizesInBytes.size() +
150 SHARED_MEMORY_CONST_OVERHEAD + sharedDummyBackend.getTotalRegisterSizeInBytes() +
sizeof(ShmForSems);
153 std::pair<size_t, size_t> SharedDummyBackend::SharedMemoryManager::getInfoOnMemory() {
154 return std::make_pair(segment.get_size(), segment.get_free_memory());
157 bool SharedDummyBackend::SharedMemoryManager::checkPidSetConsistency() {
158 unsigned pidSetSizeBeforeCleanup = pidSet->size();
160 for(
auto it = pidSet->begin(); it != pidSet->end();) {
163 it = pidSet->erase(it);
170 return pidSetSizeBeforeCleanup != 0 && pidSet->empty();
173 void SharedDummyBackend::SharedMemoryManager::reInitMemory() {
174 std::vector<std::string> nameList = listNamedElements();
176 for(
auto& item : nameList) {
177 if(item == SHARED_MEMORY_REQUIRED_VERSION_NAME) {
178 segment.destroy<
unsigned>(item.c_str());
182 else if(item != SHARED_MEMORY_PID_SET_NAME) {
186 InterruptDispatcherInterface::cleanupShm(segment);
189 std::vector<std::string> SharedDummyBackend::SharedMemoryManager::listNamedElements() {
190 std::vector<std::string> list(segment.get_num_named_objects());
192 for(
auto seg = segment.named_begin(); seg != segment.named_end(); ++seg) {
193 list.emplace_back(seg->name());
std::string getUserName()
bool processExists(unsigned pid)
boost::interprocess::vector< int32_t, ShmemAllocator > SharedMemoryVector
Exception thrown when a runtime error has occured.
std::string createShmName(std::size_t instanceIdHash, const std::string &mapFileName, const std::string &userName)
Generates shm dummy name from parameter hashes.