Skip to content

Instantly share code, notes, and snippets.

@starcatter
Created August 21, 2019 21:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save starcatter/6680585dd60819c21908bd2ffecd2ac2 to your computer and use it in GitHub Desktop.
Save starcatter/6680585dd60819c21908bd2ffecd2ac2 to your computer and use it in GitHub Desktop.
Shared memory wrapper class
#include "shmManager.h"
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include "shmStruct.h"
#include "shmManagerState.h"
using namespace boost::interprocess;
shmManager::shmManager() : state(std::make_unique<shmManagerState>()) {
try {
openMem();
}
catch (interprocess_exception& ex) {
if (ex.get_error_code() == not_found_error) {
initMem();
}
else {
throw;
}
}
{
scoped_lock<interprocess_sharable_mutex> lock(sharedData->mutex);
sharedData->users++;
}
}
shmManager::~shmManager() {
{
scoped_lock<interprocess_sharable_mutex> lock(sharedData->mutex);
sharedData->users--;
}
if (sharedData->users == 0) {
// this fails when called inside the application this class is meant to be used in.
// works fine when testing the class in a simple main method.
bool result = shared_memory_object::remove(SHARED_MEM_NAME);
printf("remove result: %d \n", result);
}
else {
printf("users remaining: %d \n", sharedData->users);
}
}
void shmManager::printStatus() {
printf("shmManager status\n\t increment -> %llu \n\t pings -> %lu \n\t users -> %u \n",
sharedData->counter, sharedData->pings, sharedData->users);
}
void shmManager::ping() {
{
scoped_lock<interprocess_sharable_mutex> lock(sharedData->mutex);
sharedData->pings++;
}
}
void shmManager::increment() {
{
scoped_lock<interprocess_sharable_mutex> lock(sharedData->mutex);
sharedData->counter++;
}
}
void shmManager::initMem() {
state->memory = std::make_unique<shared_memory_object>(create_only, SHARED_MEM_NAME, read_write);
// not in this example -- all the stuff I want to do on first memory init. It's important to me!
mapShared(true);
}
void shmManager::openMem() {
state->memory = std::make_unique<shared_memory_object>(open_only, SHARED_MEM_NAME, read_write);
// not in this example -- all the stuff I want to do when attaching to shared memory. It's important to me!
mapShared(false);
}
void shmManager::mapShared(bool init) {
printf("mapShared( [%s] )\n", ( init ? "init" : "open" ) );
state->memory->truncate(sizeof(shmStruct));
state->region = std::make_unique<mapped_region>(*state->memory, read_write);
void* addr = state->region->get_address();
sharedData = init
? new(addr) shmStruct
: static_cast<shmStruct*>(addr);
}
#ifndef SHMMANAGER_H
#define SHMMANAGER_H
#include <memory>
class shmManagerState;
class shmStruct;
const char SHARED_MEM_NAME[] = "SHARED_MEMORY";
class shmManager {
std::unique_ptr<shmManagerState> state;
public:
shmStruct* sharedData = nullptr;
shmManager();
~shmManager();
// event counter
void increment();
// task ping counter
void ping();
void printStatus();
private:
void initMem();
void openMem();
void mapShared(bool init);
};
#endif //SHMMANAGER_H
#ifndef SHMMANAGERSTATE_H
#define SHMMANAGERSTATE_H
#include <memory>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
// Can't mix boost headers with that I'm using
struct shmManagerState{
std::unique_ptr<boost::interprocess::shared_memory_object> memory;
std::unique_ptr<boost::interprocess::mapped_region> region;
};
#endif //SHMMANAGERSTATE_H
#ifndef SHMSTRUCT_H
#define SHMSTRUCT_H
#include <boost/interprocess/sync/interprocess_sharable_mutex.hpp>
struct shmStruct {
unsigned long long counter=0;
unsigned long pings=0;
unsigned int users=0;
char text[255]{0};
boost::interprocess::interprocess_sharable_mutex mutex{};
};
#endif //SHMSTRUCT_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment