Skip to content

Commit

Permalink
ioc: fix DBE_ARCHIVE handling w/ singlesource
Browse files Browse the repository at this point in the history
Stop ignoring DBE_ARCHIVE.
  • Loading branch information
mdavidsaver committed Feb 13, 2025
1 parent 775d6a9 commit 691a582
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 5 deletions.
16 changes: 16 additions & 0 deletions documentation/ioc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ Currently supported format hints are:
- Exponential
- Engineering

When subscribing, the client provided ``pvRequest`` Value may contain the field
``records._options.DBE`` with a string or unsigned integer.
This value is mapped to a DataBase Event (DBE) bit mask.

``DBE`` may be either a string or an unsigned integer.
Use of an integer is recommended.
The ``DBE_*`` macros from the ``caeventmask.h`` header may be used
(``DBE_VALUE=1``, ``DBE_ARCHIVE=2``, ``DBE_ALARM=4``).
``DBE_PROPERTY`` will be ignored if given as this event is always
handled specially.
Alternately, ``DBE`` may be a string using the old caProvider "parsing"
rules. This is not recommended.

Until UNRELEASED ``DBE_ARCHIVE`` was not handled correctly.


Group PV
^^^^^^^^

Expand Down
10 changes: 7 additions & 3 deletions ioc/singlesource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,18 @@ void subscriptionValueCallback(void* userArg, struct dbChannel* pChannel,
int, struct db_field_log* pDbFieldLog) noexcept {
auto subscriptionContext = (SingleSourceSubscriptionCtx*)userArg;
subscriptionContext->hadValueEvent = true;
auto change = UpdateType::type(UpdateType::Value | UpdateType::Alarm);
auto change = subscriptionContext->pValueEventSubscription.mask;
#if EPICS_VERSION_INT >= VERSION_INT(7, 0, 6, 0)
if(pDbFieldLog) {
// when available, use DBE mask from db_field_log
change = UpdateType::type(pDbFieldLog->mask & UpdateType::Everything);
change = pDbFieldLog->mask;
}
#endif
subscriptionCallback(subscriptionContext, change, pChannel, pDbFieldLog);
// ARCHIVE events will get the same data fields as VALUE
if(change & DBE_ARCHIVE)
change = (change&~DBE_ARCHIVE)|DBE_VALUE;
change &= UpdateType::Everything; // does not include DBE_ARCHIVE
subscriptionCallback(subscriptionContext, UpdateType::type(change), pChannel, pDbFieldLog);
}

void subscriptionPropertiesCallback(void* userArg, struct dbChannel* pChannel, int,
Expand Down
2 changes: 2 additions & 0 deletions ioc/subscriptionctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace ioc {
class Subscription {
std::shared_ptr<std::remove_pointer<dbEventSubscription>::type> sub; // holds void* returned by db_add_event()
public:
unsigned mask=0;
/* Add a subscription event by calling db_add_event using the given subscriptionCtx
* and selecting the correct elements based on the given type of event being added.
* You need to specify the correct options that correspond to the event type.
Expand All @@ -45,6 +46,7 @@ class Subscription {
});
if(!sub)
throw std::runtime_error("Failed to create db subscription");
mask = select;
}
void cancel() {
sub.reset();
Expand Down
13 changes: 12 additions & 1 deletion test/testpvreq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,21 @@ void testArgs()
);
}

void testDBE()
{
testShow()<<__func__;

{
auto v(client::Context::request().pvRequest("record[DBE=VALUE]").build());
testEq(v["record._options.DBE"].as<std::string>(), "VALUE");
}
}

} // namespace

MAIN(testpvreq)
{
testPlan(38);
testPlan(39);
testSetup();
logger_config_env();
testPvRequest();
Expand All @@ -409,6 +419,7 @@ MAIN(testpvreq)
testError();
testBuilder();
testArgs();
testDBE();
cleanup_for_valgrind();
return testDone();
}
32 changes: 31 additions & 1 deletion test/testqsingle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <asTrapWrite.h>
#include <generalTimeSup.h>

#include "dblocker.h"
#include "testioc.h"
#include "utilpvt.h"

Expand Down Expand Up @@ -874,11 +875,39 @@ void testMonitorAIFilt(TestClient& ctxt)
sub2.testEmpty();
}

void testMonitorDBE(TestClient& ctxt)
{
testDiag("%s", __func__);

TestSubscription sub(ctxt.monitor("test:ai.TPRO")
.record("DBE", DBE_ARCHIVE)
.maskConnected(true)
.maskDisconnected(true));

auto val(sub.waitForUpdate());
testShow()<<val.format().delta();

auto prec(testdbRecordPtr("test:ai"));

{
ioc::DBLocker L(prec);

prec->tpro = 42; // event discarded
db_post_events(prec, &prec->tpro, DBE_VALUE);
prec->tpro = 43;
db_post_events(prec, &prec->tpro, DBE_VALUE|DBE_ARCHIVE);
}

val = sub.waitForUpdate();
testShow()<<val.format().delta();
testEq(val["value"].as<int32_t>(), 43);
}

} // namespace

MAIN(testqsingle)
{
testPlan(88);
testPlan(89);
testSetup();
pvxs::logger_config_env();
generalTimeRegisterCurrentProvider("test", 1, &testTimeCurrent);
Expand Down Expand Up @@ -921,6 +950,7 @@ MAIN(testqsingle)
testMonitorAI(mctxt);
testMonitorBO(mctxt);
testMonitorAIFilt(mctxt);
testMonitorDBE(mctxt);
}
timeSim = false;
testPutBlock();
Expand Down

0 comments on commit 691a582

Please sign in to comment.