2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 <2019> 2020 2021 2022 2023 2024 2025 | Index | 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 <2019> 2020 2021 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Strange change in behavior from 7.0.1 to 7.0.2 |
From: | "Johnson, Andrew N. via Core-talk" <[email protected]> |
To: | Michael Davidsaver <[email protected]>, "Rivers, Mark L." <[email protected]>, "[email protected]" <[email protected]> |
Date: | Thu, 24 Jan 2019 23:49:39 +0000 |
On 1/24/19 12:54 PM, Michael Davidsaver wrote:I hope you aren't considering generating lists or trees of records at runtime...Seems like the best course is for dbProcess() and processTarget() to keep track of which records are being recursed into. BTW contrary to what I wrote below RPRO wouldn't need to store the ID, only PUTF would, although unfortunately PUTF is currently visible externally (but is SPC_NOMOD). Just noticed that epicsAtomicIncrIntT() implements undefined behaviour if it wraps because it operates on a signed integer, so we couldn't use that to generate a 'unique-enough' ID anyway.I could see of a way around this by storing an identifier in the PUTF and RPRO fields which would let us see that (I'd make the PUTF and RPRO fields into DBF_LONG and use an atomic counter to generate a unique ID for each source put).I was thinking of using a stack address, or maybe epicsThread*, from the thread which is doing the processing. Not really fundamentally different from a global counter, though maybe easier to debug. This would be set and cleared by dbProcess(). BTW just changing the 'else if' in processTarget() to this fixes Mark's database, but breaks asyncproctest:else if (psrc->putf && psrc->putf != pdst->putf) { I wonder using if the pointer to the record that received the original put would be sufficiently unique as an ID? When two puts come into the same record before async completion the second put would not set RPRO, but since RPRO is already true we'd just avoid setting it the second time. Using a dbCommon* also allows for even nicer debug/trace messages, we can print the put-record's name in the trace messages in processTarget().# ===== Chain 2 again ====== ok 11 - dbPutField("chain2:1.B", 5, ...) -> 0 (Success) ok 12 - dbPutField("chain2:1.B", 5, ...) -> 0 (Success) ok 13 - dbPutField("chain2:1.B", 5, ...) -> 0 (Success) Bail out! Processing timed out Abort The existing PUTF field is so close to being sufficient; I would much prefer to use it for this than duplicate it, the external visibility is the main problem I see. Any driver/record (such as the tpmac) which writes or writes directly to the field will break, but nobody should be fiddling with dbCommon fields like that.I'm not sure about hijacking the existing flag fields. Maybe add a new field in dbCommonPvt? I'm working on adding a new special() type to allow read-only access to some dbCommon fields that need a little pre-processing — I've wanted to support getting the TIME field for years, so this is just another field to handle in the same way. My dbCommon *PUTF is now working with that... I don't like hiding per-record data in pvCommonPvt. IMHO the recnode field there should have been another DBF_NOACCESS SPC_NOMOD extra() field added to dbCommon.dbd just like every other IOC subsystem field. - Andrew -- Arguing for surveillance because you have nothing to hide is no different than making the claim, "I don't care about freedom of speech because I have nothing to say." -- Edward Snowdon |