- 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(); entryId = octetStringVal.getOctetString();
octetStringVal.Dispose();
return entryId; return entryId;
} }
else else

@ -1549,7 +1549,7 @@ typedef enum {
RCB_EVENT_GI, /* << GI report triggered */ RCB_EVENT_GI, /* << GI report triggered */
RCB_EVENT_PURGEBUF, /* << Purge buffer procedure executed */ RCB_EVENT_PURGEBUF, /* << Purge buffer procedure executed */
RCB_EVENT_OVERFLOW, /* << Report buffer overflow */ 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; } IedServer_RCBEventType;
/** /**

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

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

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

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

Loading…
Cancel
Save