Skip to content
Snippets Groups Projects
Commit 9ee923cb authored by benjamin.franksen's avatar benjamin.franksen
Browse files

seq: moved code from proc_db_events_queued into proc_db_events

parent 270218d1
No related branches found
No related tags found
No related merge requests found
...@@ -33,9 +33,14 @@ in the file LICENSE that is included with this distribution. ...@@ -33,9 +33,14 @@ in the file LICENSE that is included with this distribution.
#include "seq.h" #include "seq.h"
#include "seq_debug.h" #include "seq_debug.h"
static void proc_db_events(pvValue *value, pvType type, static void proc_db_events(
CHAN *ch, SSCB *ss, pvEventType evtype, pvStat status); pvValue *value, /* ptr to value */
static void proc_db_events_queued(SPROG *sp, CHAN *ch, pvValue *value); pvType type, /* type of value */
CHAN *ch, /* channel object */
SSCB *ss, /* originator, for put and get, else 0 */
pvEventType evtype, /* put, get, or monitor */
pvStat status /* status from pv layer */
);
/* /*
* seq_connect() - Initiate connect & monitor requests to PVs. * seq_connect() - Initiate connect & monitor requests to PVs.
...@@ -183,8 +188,7 @@ static void seq_mon_handler( ...@@ -183,8 +188,7 @@ static void seq_mon_handler(
DBCHAN *dbch = ch->dbch; DBCHAN *dbch = ch->dbch;
assert(dbch != NULL); assert(dbch != NULL);
/* Process event handling in each state set */ proc_db_events(value, type, ch, 0, pvEventMonitor, status);
proc_db_events(value, type, ch, sp->ss, pvEventMonitor, status);
if (!dbch->gotOneMonitor) if (!dbch->gotOneMonitor)
{ {
dbch->gotOneMonitor = TRUE; dbch->gotOneMonitor = TRUE;
...@@ -220,14 +224,29 @@ void seq_event_handler( ...@@ -220,14 +224,29 @@ void seq_event_handler(
} }
} }
struct putq_cp_arg {
CHAN *ch;
void *value;
};
static void *putq_cp(void *dest, const void *src, size_t elemSize)
{
struct putq_cp_arg *arg = (struct putq_cp_arg *)src;
CHAN *ch = arg->ch;
return memcpy(dest, arg->value,
pv_size_n(ch->type->getType, ch->dbch->dbCount));
}
/* Common code for completion and monitor handling */ /* Common code for completion and monitor handling */
static void proc_db_events( static void proc_db_events(
pvValue *value, pvValue *value,
pvType type, pvType type,
CHAN *ch, CHAN *ch,
SSCB *ss, /* originator, for put and get */ SSCB *ss,
pvEventType evtype, pvEventType evtype,
pvStat status) pvStat status
)
{ {
SPROG *sp = ch->sprog; SPROG *sp = ch->sprog;
DBCHAN *dbch = ch->dbch; DBCHAN *dbch = ch->dbch;
...@@ -238,54 +257,73 @@ static void proc_db_events( ...@@ -238,54 +257,73 @@ static void proc_db_events(
DEBUG("proc_db_events: var=%s, pv=%s, type=%s, status=%d\n", ch->varName, DEBUG("proc_db_events: var=%s, pv=%s, type=%s, status=%d\n", ch->varName,
dbch->dbName, event_type_name[evtype], status); dbch->dbName, event_type_name[evtype], status);
/* If monitor on var queued via syncQ, branch to alternative routine */ /* monitor on var queued via syncQ */
if (ch->queue && evtype == pvEventMonitor) if (ch->queue && evtype == pvEventMonitor)
{ {
proc_db_events_queued(sp, ch, value); boolean full;
return; struct putq_cp_arg arg = {ch, value};
DEBUG("proc_db_events: var=%s, pv=%s, queue=%p, used(max)=%d(%d)\n",
ch->varName, ch->dbch->dbName,
ch->queue, seqQueueUsed(ch->queue), seqQueueNumElems(ch->queue));
/* Copy whole message into queue; no need to lock against other
writers, because named and anonymous PVs are disjoint. */
full = seqQueuePutF(ch->queue, putq_cp, &arg);
if (full)
{
errlogSevPrintf(errlogMinor,
"monitor event for variable %s (pv %s): "
"last queue element overwritten (queue is full)\n",
ch->varName, ch->dbch->dbName
);
}
} }
else
/* Copy value and meta data into user variable shared buffer
(can get NULL value pointer for put completion only) */
if (value != NULL)
{ {
void *val = pv_value_ptr(value,type); /* Copy value and meta data into user variable shared buffer
PVMETA meta; (can get NULL value pointer for put completion only) */
if (value != NULL)
{
void *val = pv_value_ptr(value,type);
PVMETA meta;
/* must not use an initializer here, the MS C compiler chokes on it */ /* must not use an initializer here, the MS C compiler chokes on it */
meta.timeStamp = pv_stamp(value,type); meta.timeStamp = pv_stamp(value,type);
meta.status = pv_status(value,type); meta.status = pv_status(value,type);
meta.severity = pv_severity(value,type); meta.severity = pv_severity(value,type);
meta.message = NULL; meta.message = NULL;
/* Set error message only when severity indicates error */ /* Set error message only when severity indicates error */
if (meta.severity != pvSevrNONE) if (meta.severity != pvSevrNONE)
{ {
const char *pmsg = pvVarGetMess(dbch->pvid); const char *pmsg = pvVarGetMess(dbch->pvid);
if (!pmsg) pmsg = "unknown"; if (!pmsg) pmsg = "unknown";
meta.message = pmsg; meta.message = pmsg;
} }
/* Write value and meta data to shared buffers. /* Write value and meta data to shared buffers.
Set the dirty flag only if this was a monitor event. */ Set the dirty flag only if this was a monitor event. */
ss_write_buffer(ch, val, &meta, evtype == pvEventMonitor); ss_write_buffer(ch, val, &meta, evtype == pvEventMonitor);
} }
/* Signal completion */ /* Signal completion */
switch (evtype) if (ss)
{ {
case pvEventGet: switch (evtype)
epicsEventSignal(ss->getSemId[chNum(ch)]); {
break; case pvEventGet:
case pvEventPut: epicsEventSignal(ss->getSemId[chNum(ch)]);
epicsEventSignal(ss->putSemId[chNum(ch)]); break;
break; case pvEventPut:
default: epicsEventSignal(ss->putSemId[chNum(ch)]);
break; break;
default:
break;
}
}
} }
/* If there's an event flag associated with this channel, set it */ /* If there's an event flag associated with this channel, set it */
/* TODO: check if correct/documented to do this for non-monitor completions */
if (ch->syncedTo) if (ch->syncedTo)
seq_efSet(sp->ss, ch->syncedTo); seq_efSet(sp->ss, ch->syncedTo);
...@@ -293,46 +331,6 @@ static void proc_db_events( ...@@ -293,46 +331,6 @@ static void proc_db_events(
ss_wakeup(sp, ch->eventNum); ss_wakeup(sp, ch->eventNum);
} }
struct putq_cp_arg {
CHAN *ch;
void *value;
};
static void *putq_cp(void *dest, const void *src, size_t elemSize)
{
struct putq_cp_arg *arg = (struct putq_cp_arg *)src;
CHAN *ch = arg->ch;
return memcpy(dest, arg->value,
pv_size_n(ch->type->getType, ch->dbch->dbCount));
}
/* Common code for event and callback handling (queuing version) */
static void proc_db_events_queued(SPROG *sp, CHAN *ch, pvValue *value)
{
boolean full;
struct putq_cp_arg arg = {ch, value};
DEBUG("proc_db_events_queued: var=%s, pv=%s, queue=%p, used(max)=%d(%d)\n",
ch->varName, ch->dbch->dbName,
ch->queue, seqQueueUsed(ch->queue), seqQueueNumElems(ch->queue));
/* Copy whole message into queue; no need to lock against other
writers, because named and anonymous PVs are disjoint. */
full = seqQueuePutF(ch->queue, putq_cp, &arg);
if (full)
{
errlogSevPrintf(errlogMinor,
"monitor event for variable '%s' (pv '%s'): "
"last queue element overwritten (queue is full)\n",
ch->varName, ch->dbch->dbName
);
}
/* Set event flag; note: it doesn't matter which state set we pass. */
seq_efSet(sp->ss, ch->syncedTo);
/* Wake up each state set that uses this channel in an event */
ss_wakeup(sp, ch->eventNum);
}
/* Disconnect all database channels */ /* Disconnect all database channels */
void seq_disconnect(SPROG *sp) void seq_disconnect(SPROG *sp)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment