Ta emot systemhändelser
ProviewR skickar ut medelanden vi olika händelser, t ex, när en mjuk omstart pågår eller
om runtimmiljön stoppas. En applikation kan avlyssna dessa händelser, för att t ex terminera
när ProviewR stoppas. Avlyssningen sker via Qcom. Man skapar en Qcom kö, och knyter denna
kö till den kö som meddelandena sänds ut på.
#include "rt_qcom.h"
#include "rt_ini_event.h"
#include "rt_qcom_msg.h"
qcom_sQid qid = qcom_cNQid;
qcom_sQid qini;
qcom_sQattr qAttr;
if ( !qcom_Init(&sts, 0, "ra_myappl")) {
throw co_error(sts);
// Create a queue to receive stop and restart events
qAttr.type = qcom_eQtype_private;
qAttr.quota = 100;
if ( !qcom_CreateQ(&sts, &qid, &qAttr, "events"))
throw co_error(sts);
// Bind to init event queue
qini = qcom_cQini;
if ( !qcom_Bind(&sts, qid, &qini))
throw co_error(sts);
I varje scan läser man av kön med qcom_Get() för att se om något meddelande har kommit. Man
kan även passa på att använda timeouten i qcom_Get() för att vänta till nästa scan.
I exemplet nedan hanterar man dels terminate meddelandet, men även oldPlcStop och swapDone
som markerar början och slutet på en mjuk omstart. Det behöver man enbart göra om man vill att
applikationen ska kunna upptäcka nya objekt eller konfigureringar vid en mjuk omstart.
int tmo = 1000;
char mp[2000];
qcom_sGet get;
int swap = 0;
for (;;) {
get.maxSize = sizeof(mp);
get.data = mp;
qcom_Get( &sts, &qid, &get, tmo);
if (sts == QCOM__TMO || sts == QCOM__QEMPTY) {
if ( !swap)
// Do the normal thing
scan();
}
else {
// Ini event received
ini_mEvent new_event;
qcom_sEvent *ep = (qcom_sEvent*) get.data;
new_event.m = ep->mask;
if (new_event.b.oldPlcStop && !swap) {
errh_SetStatus( PWR__APPLRESTART);
swap = 1;
close();
} else if (new_event.b.swapDone && swap) {
swap = 0;
open();
errh_SetStatus( PWR__ARUN);
} else if (new_event.b.terminate) {
exit(0);
}
}
}
Om man endast är intresserad av att stoppa processen när ProviewR tas ner, finns det ett
enklare sätt att ta död på den. Man kan lägga en scriptfile pwrp_stop.sh på $pwrp_exe där
man gör kill på processen.
killall ra_myappl