60using namespace EVENTSLIB;
66static const std::string defaultSharedMemoryBufferKey(
"MNE_EVENTS_SHAREDMEMORY_BUFFER");
67static const std::string defaultGroupName(
"external");
69int EVENTSINTERNAL::EventSharedMemManager::m_iLastUpdateIndex(0);
75constexpr static int bufferLength(5);
76static long long defatult_timerBufferWatch(200);
87: m_EventSample(sample)
98 return m_CreationTime;
105 return m_EventSample;
119 return m_TypeOfUpdate;
133 return EVENTSINTERNAL::EventUpdateTypeString[m_TypeOfUpdate];
139: m_pEventManager(parent)
140, m_SharedMemory(QString::fromStdString(defaultSharedMemoryBufferKey))
142, m_sGroupName(defaultGroupName)
143, m_bGroupCreated(false)
145, m_SharedMemorySize(sizeof(int) + bufferLength * sizeof(
EventUpdate))
146, m_fTimerCheckBuffer(defatult_timerBufferWatch)
147, m_BufferWatcherThreadRunning(false)
148, m_WritingToSharedMemory(false)
151, m_SharedBuffer(nullptr)
153, m_Mode(EVENTSLIB::SharedMemoryMode::READ)
160EVENTSINTERNAL::EventSharedMemManager::~EventSharedMemManager()
162 detachFromSharedMemory();
163 delete[] m_LocalBuffer;
175 detachFromSharedMemory();
178 if(m_Mode == EVENTSLIB::SharedMemoryMode::READ)
180 attachToSharedSegment(QSharedMemory::AccessMode::ReadOnly);
181 launchSharedMemoryWatcherThread();
183 }
else if(m_Mode == EVENTSLIB::SharedMemoryMode::WRITE)
185 attachToOrCreateSharedSegment( QSharedMemory::AccessMode::ReadWrite);
186 }
else if(m_Mode == EVENTSLIB::SharedMemoryMode::READWRITE)
188 attachToOrCreateSharedSegment( QSharedMemory::AccessMode::ReadWrite);
189 launchSharedMemoryWatcherThread();
196void EVENTSINTERNAL::EventSharedMemManager::attachToOrCreateSharedSegment(QSharedMemory::AccessMode mode)
198 attachToSharedSegment(mode);
201 m_IsInit = createSharedSegment(m_SharedMemorySize, mode);
207void EVENTSINTERNAL::EventSharedMemManager::attachToSharedSegment(QSharedMemory::AccessMode mode)
209 m_IsInit = m_SharedMemory.attach(mode);
212 m_SharedBuffer =
static_cast<EventUpdate*
>(m_SharedMemory.data());
218bool EVENTSINTERNAL::EventSharedMemManager::createSharedSegment(
int bufferSize, QSharedMemory::AccessMode mode)
220 bool output = m_SharedMemory.create(bufferSize, mode);
223 m_SharedBuffer =
static_cast<EventUpdate*
>(m_SharedMemory.data());
224 initializeSharedMemory();
231void EVENTSINTERNAL::EventSharedMemManager::launchSharedMemoryWatcherThread()
233 m_BufferWatcherThread = std::thread(&EventSharedMemManager::bufferWatcher,
this);
238void EVENTSINTERNAL::EventSharedMemManager::detachFromSharedMemory()
240 stopSharedMemoryWatcherThread();
241 if(!m_BufferWatcherThreadRunning && !m_WritingToSharedMemory)
243 if(m_SharedMemory.isAttached())
245 m_SharedMemory.detach();
252void EVENTSINTERNAL::EventSharedMemManager::stopSharedMemoryWatcherThread()
254 if(m_BufferWatcherThreadRunning)
257 m_BufferWatcherThread.join();
265 detachFromSharedMemory();
281 (m_Mode == EVENTSLIB::SharedMemoryMode::WRITE ||
282 m_Mode == EVENTSLIB::SharedMemoryMode::READWRITE ) )
284 EventUpdate newUpdate(sample, m_Id, EventUpdateType::NEW_EVENT);
285 copyNewUpdateToSharedMemory(newUpdate);
294 (m_Mode == EVENTSLIB::SharedMemoryMode::WRITE ||
295 m_Mode == EVENTSLIB::SharedMemoryMode::READWRITE ) )
297 EventUpdate newUpdate(sample, m_Id, EventUpdateType::DELETE_EVENT);
298 copyNewUpdateToSharedMemory(newUpdate);
304void EVENTSINTERNAL::EventSharedMemManager::initializeSharedMemory()
308 void* localBuffer =
static_cast<void*
>(m_LocalBuffer);
309 char* sharedBuffer =
static_cast<char*
>(m_SharedMemory.data()) +
sizeof(
int);
310 int indexIterator(0);
311 m_WritingToSharedMemory =
true;
312 if(m_SharedMemory.isAttached())
314 m_SharedMemory.lock();
315 memcpy(m_SharedMemory.data(), &indexIterator,
sizeof(
int));
316 memcpy(sharedBuffer, localBuffer, bufferLength *
sizeof(
EventUpdate));
317 m_SharedMemory.unlock();
319 m_WritingToSharedMemory =
false;
324void EVENTSINTERNAL::EventSharedMemManager::copyNewUpdateToSharedMemory(EventUpdate& newUpdate)
328 char* sharedBuffer =
static_cast<char*
>(m_SharedMemory.data()) +
sizeof(
int);
329 int indexIterator(0);
330 m_WritingToSharedMemory =
true;
331 if(m_SharedMemory.isAttached())
333 m_SharedMemory.lock();
334 memcpy(&indexIterator, m_SharedMemory.data(),
sizeof(
int));
335 memcpy(m_SharedMemory.data(), &(++indexIterator),
sizeof(
int));
336 int index = (indexIterator-1) % bufferLength;
337 memcpy(sharedBuffer + (index *
sizeof(EventUpdate)),
static_cast<void*
>(&newUpdate),
sizeof(EventUpdate));
338 m_SharedMemory.unlock();
340 m_WritingToSharedMemory =
false;
345void EVENTSINTERNAL::EventSharedMemManager::copySharedMemoryToLocalBuffer()
347 void* localBuffer =
static_cast<void*
>(m_LocalBuffer);
348 char* sharedBuffer =
static_cast<char*
>(m_SharedMemory.data()) +
sizeof(
int);
349 if(m_SharedMemory.isAttached())
351 m_SharedMemory.lock();
352 memcpy(localBuffer, sharedBuffer, bufferLength *
sizeof(EventUpdate));
353 m_SharedMemory.unlock();
361void EVENTSINTERNAL::EventSharedMemManager::bufferWatcher()
363 m_BufferWatcherThreadRunning =
true;
368 copySharedMemoryToLocalBuffer();
369 auto timeCheck = getTimeNow();
370 processLocalBuffer();
371 m_lastCheckTime = timeCheck;
372 std::this_thread::sleep_for(std::chrono::milliseconds(m_fTimerCheckBuffer));
374 m_BufferWatcherThreadRunning =
false;
379void EVENTSINTERNAL::EventSharedMemManager::processLocalBuffer()
381 for(
int i = 0; i < bufferLength; ++i)
384 if(m_LocalBuffer[i].getCreationTime() > m_lastCheckTime &&
385 m_LocalBuffer[i].getCreatorId() != m_Id )
387 createGroupIfNeeded();
388 processEvent(m_LocalBuffer[i]);
400 case EventUpdateType::NEW_EVENT :
405 case EventUpdateType::DELETE_EVENT :
407 processDeleteEvent(ne);
417void EVENTSINTERNAL::EventSharedMemManager::processNewEvent(
const EventUpdate& ne)
420 m_pEventManager->generateNewEventId(), ne.
getSample(), m_GroupId);
421 m_pEventManager->insertEvent(newEvent);
426void EVENTSINTERNAL::EventSharedMemManager::processDeleteEvent(
const EventUpdate& ne)
428 auto eventsInSample = m_pEventManager->getEventsInSample(ne.getSample());
429 for(
auto& e: *eventsInSample)
431 if(e.groupId == m_GroupId)
433 m_pEventManager->eraseEvent(e.id);
443 const auto tNow = std::chrono::system_clock::now();
444 return std::chrono::duration_cast<std::chrono::milliseconds>(
445 tNow.time_since_epoch()).count();
450void EVENTSINTERNAL::EventSharedMemManager::createGroupIfNeeded()
456 m_bGroupCreated =
true;
462void EVENTSINTERNAL::EventSharedMemManager::printLocalBuffer()
464 for(
int i = 0; i < bufferLength; ++i)
466 qDebug() <<
"[" << i <<
"] -" << m_LocalBuffer[i].eventTypeToText().c_str()
467 <<
"-" << m_LocalBuffer[i].getSample()
468 <<
"-" << m_LocalBuffer[i].getCreatorId()
469 <<
"-" << m_LocalBuffer[i].getCreationTime() <<
"\n";
EventSharedMemManager definition.
EventManager declaration.
EventGroup class is designed as a data holder for a group. It is designed towards ease of use for a c...
void setType(enum EventUpdateType t)
long long getCreationTime() const
std::string eventTypeToText()
enum EventUpdateType getType() const
EventSharedMemManager(EVENTSLIB::EventManager *parent=nullptr)
void init(EVENTSLIB::SharedMemoryMode mode)
void processEvent(const EventUpdate &ne)
void deleteEvent(int sample)
void addEvent(int sample)
static long long getTimeNow()