- server reporting: added code to prevent race condition with

RCBEventHandler
pull/396/head
Michael Zillgith 3 years ago
parent bb7c2421cd
commit c76b5dd2da

@ -1529,6 +1529,8 @@ namespace IEC61850
entryId = octetStringVal.getOctetString();
octetStringVal.Dispose();
return entryId;
}
else

@ -1549,7 +1549,7 @@ typedef enum {
RCB_EVENT_GI, /* << GI report triggered */
RCB_EVENT_PURGEBUF, /* << Purge buffer procedure executed */
RCB_EVENT_OVERFLOW, /* << Report buffer overflow */
RCB_EVENT_REPORT_CREATED /* << a new report was created and inserted into the buffer */
RCB_EVENT_REPORT_CREATED /* << A new report was created and inserted into the buffer */
} IedServer_RCBEventType;
/**

@ -323,7 +323,9 @@ struct sMmsMapping {
#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
/* flag indicates if data model is locked --> prevents reports to be sent */
bool isModelLocked;
Semaphore isModelLockedMutex;
IedServer iedServer;

@ -811,9 +811,13 @@ IedServer_stopThreadless(IedServer self)
void
IedServer_lockDataModel(IedServer self)
{
Semaphore_wait(self->mmsMapping->isModelLockedMutex);
MmsServer_lockModel(self->mmsServer);
self->mmsMapping->isModelLocked = true;
Semaphore_post(self->mmsMapping->isModelLockedMutex);
}
void
@ -827,9 +831,13 @@ IedServer_unlockDataModel(IedServer self)
/* check if reports have to be sent! */
Reporting_processReportEventsAfterUnlock(self->mmsMapping);
Semaphore_wait(self->mmsMapping->isModelLockedMutex);
self->mmsMapping->isModelLocked = false;
MmsServer_unlockModel(self->mmsServer);
Semaphore_post(self->mmsMapping->isModelLockedMutex);
}
#if (CONFIG_IEC61850_CONTROL_SERVICE == 1)

@ -2029,6 +2029,12 @@ MmsMapping_create(IedModel* model, IedServer iedServer)
self->settingGroups = LinkedList_create();
#endif
self->isModelLocked = false;
#if (CONFIG_MMS_THREADLESS_STACK != 1)
self->isModelLockedMutex = Semaphore_create(1);
#endif
self->attributeAccessHandlers = LinkedList_create();
/* create data model specification */
@ -2119,6 +2125,10 @@ MmsMapping_destroy(MmsMapping* self)
if (self->locbTrk) GLOBAL_FREEMEM(self->locbTrk);
#endif
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->isModelLockedMutex);
#endif
LinkedList_destroy(self->attributeAccessHandlers);
IedModel_setAttributeValuesToNull(self->model);
@ -3654,6 +3664,8 @@ MmsMapping_triggerReportObservers(MmsMapping* self, MmsValue* value, int flag)
{
LinkedList element = self->reportControls;
Semaphore_wait(self->isModelLockedMutex);
bool modelLocked = self->isModelLocked;
while ((element = LinkedList_getNext(element)) != NULL) {
@ -3689,6 +3701,8 @@ MmsMapping_triggerReportObservers(MmsMapping* self, MmsValue* value, int flag)
if (modelLocked == false) {
Reporting_processReportEventsAfterUnlock(self);
}
Semaphore_post(self->isModelLockedMutex);
}
#endif /* (CONFIG_IEC61850_REPORT_SERVICE == 1) */
@ -3700,8 +3714,6 @@ MmsMapping_triggerGooseObservers(MmsMapping* self, MmsValue* value)
{
LinkedList element = self->gseControls;
bool modelLocked = self->isModelLocked;
while ((element = LinkedList_getNext(element)) != NULL) {
MmsGooseControlBlock gcb = (MmsGooseControlBlock) element->data;
@ -3711,9 +3723,13 @@ MmsMapping_triggerGooseObservers(MmsMapping* self, MmsValue* value)
if (DataSet_isMemberValue(dataSet, value, NULL)) {
MmsGooseControlBlock_setStateChangePending(gcb);
if (modelLocked == false) {
Semaphore_wait(self->isModelLockedMutex);
if (self->isModelLocked == false) {
MmsGooseControlBlock_publishNewState(gcb);
}
Semaphore_post(self->isModelLockedMutex);
}
}
}

@ -3062,10 +3062,6 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_
exit_function:
if (overflow) {
/* TODO call user callback handler */
}
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(buffer->lock);
#endif
@ -3819,6 +3815,8 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs)
void
Reporting_processReportEvents(MmsMapping* self, uint64_t currentTimeInMs)
{
Semaphore_wait(self->isModelLockedMutex);
if (self->isModelLocked == false) {
LinkedList element = self->reportControls;
@ -3833,6 +3831,8 @@ Reporting_processReportEvents(MmsMapping* self, uint64_t currentTimeInMs)
ReportControl_unlockNotify(rc);
}
}
Semaphore_post(self->isModelLockedMutex);
}
/*

Loading…
Cancel
Save