EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  <20222023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  <20222023  2024 
<== Date ==> <== Thread ==>

Subject: Re: How to safely implement an asynPortDriver with SCAN records
From: Érico Nogueira Rolim via Tech-talk <tech-talk at aps.anl.gov>
To: Michael Davidsaver <mdavidsaver at gmail.com>, Jure Varlec <jure.varlec at cosylab.com>
Cc: tech-talk <tech-talk at aps.anl.gov>
Date: Fri, 22 Jul 2022 15:04:27 -0300
On 20/07/2022 14:20, Michael Davidsaver wrote:
On 7/20/22 08:32, Jure Varlec wrote:
I'm not sure killing the IOC with cantProceed() is the best way to handle this.

My use of canProceed() is to make clear that the destructor
asynPortDriver::~asynPortDriver should __never__ be executed.


Indeed, upon rereading your original message I realize I had completely misunderstood your point. Thank you for re-iterating it.




Have you tried disabling the port as I suggested? You can modify your exit hook like so:

static void exitHandlerC(void *pPvt)
{
     drvFOFB *pdrvFOFB = (drvFOFB *)pPvt;
     pasynManager->enable(pdrvFOFB->pasynUserSelf, 0);

This part if fine.  I think it should block unless concurrent
operations on the asyn port complete, and prevent future
operations initiated through an asynUser* (unless they
first re-enable the port).

     delete pdrvFOFB;

imo. it is reasonable to join worker threads here, but I would
recommend against deleting.

Please keep in mind that delete leaves dangling pointers in the
asyn port.  imo. this is an invitation for the chaos of
use-after-free errors.


}

This should be enough to prevent further calls into your driver, thus preventing the crash. It may print harmless error messages, but that's all.

... as long as nothing re-enables the port.


Disabling the scan threads cannot be done without modifying epics-base. Running the hook at a different point (e.g. at initHookAfterStopScan) won't help, the threads are/never/​ stopped.

Best,
Jure
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ *From:* Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Érico Nogueira Rolim via Tech-talk <tech-talk at aps.anl.gov>
*Sent:* Wednesday, July 20, 2022 16:18
*To:* Michael Davidsaver <mdavidsaver at gmail.com>; Mark Rivers <rivers at cars.uchicago.edu>; Andrew Johnson <anj at anl.gov>
*Cc:* tech-talk <tech-talk at aps.anl.gov>
*Subject:* Re: How to safely implement an asynPortDriver with SCAN records
Caution: This email originated from outside of Cosylab.


On 08/07/2022 17:37, Michael Davidsaver wrote:
On 7/8/22 11:11, Mark Rivers via Tech-talk wrote:
Hi Andrew,

To be honest I have not paid enough attention to how to correctly
handle destructors in asynPortDriver.

On the occasions when I've used asynPortDriver, I put a cantProceed()
in the sub-class destructor.


Can you say where exactly in the destructor you used cantProceed()? I
can't seem to make it behave correctly: the IOC never exits, though it
does dump a stack trace.



After a call to registerInterface(), the asynInterface::drvPvt pointer
must remain valid until
the process exits.  So an asyn port can't be destroyed.


I've toyed with the ideas like re-counter asynUser, or somehow later
setting drvPvt=NULL.
Both seem possible, but not without quite some effort.


This situation is made more complicated by the fact that IOC scan
threads are not stopped on exit.
We do now stop them during database unit tests.  However, some ~vague
compatibility concerns have
so far kept this from being done for full IOCs.


Where does this choice happen? Could one do it for their own IOC?




Personally, as a matter of good practice, drivers I write always
include an epicsAtExit() handler
which stops any worker threads.


Also, I should mention the de-init hooks added in Base 7.0.4 to
decouple database shutdown from
process exit.

https://github.com/epics-base/epics-base/commit/5d5e552a7ec6ef69459c97b0081aa775372a6290#diff-02e4602d43dbb03b4097bb26382a1db92367fb55fe791415cd32d4f234875d92R50 <https://github.com/epics-base/epics-base/commit/5d5e552a7ec6ef69459c97b0081aa775372a6290#diff-02e4602d43dbb03b4097bb26382a1db92367fb55fe791415cd32d4f234875d92R50>


For compatibility, the effect of initHookAtShutdown can mostly be
replicated by calling epicsAtExit()
at initHookAfterIocRunning.


If I understand correctly, what I'd want for my own code would be
calling the driver's destructor in initHookAfterStopScan? If it ran for
full IOCs, of course.


Aviso Legal: Esta mensagem e seus anexos podem conter informações confidenciais e/ou de uso restrito. Observe atentamente seu conteúdo e considere eventual consulta ao remetente antes de copiá-la, divulgá-la ou distribuí-la. Se você recebeu esta mensagem por engano, por favor avise o remetente e apague-a imediatamente.

Disclaimer: This email and its attachments may contain confidential and/or privileged information. Observe its content carefully and consider possible querying to the sender before copying, disclosing or distributing it. If you have received this email by mistake, please notify the sender and delete it immediately.



References:
How to safely implement an asynPortDriver with SCAN records Érico Nogueira Rolim via Tech-talk
RE: How to safely implement an asynPortDriver with SCAN records Mark Rivers via Tech-talk
Re: How to safely implement an asynPortDriver with SCAN records Érico Nogueira Rolim via Tech-talk
Re: How to safely implement an asynPortDriver with SCAN records Andrew Johnson via Tech-talk
RE: How to safely implement an asynPortDriver with SCAN records Mark Rivers via Tech-talk
Re: How to safely implement an asynPortDriver with SCAN records Michael Davidsaver via Tech-talk
Re: How to safely implement an asynPortDriver with SCAN records Érico Nogueira Rolim via Tech-talk
Re: How to safely implement an asynPortDriver with SCAN records Jure Varlec via Tech-talk
Re: How to safely implement an asynPortDriver with SCAN records Michael Davidsaver via Tech-talk

Navigate by Date:
Prev: ci-scripts 3.4 release: more cross-compiling options, Python hooks Ralph Lange via Tech-talk
Next: EPICS AD support for XC-Actaeon detector? Miceli, Antonino via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  <20222023  2024 
Navigate by Thread:
Prev: Re: How to safely implement an asynPortDriver with SCAN records Michael Davidsaver via Tech-talk
Next: PHP_EPICS module Remi Faure via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  <20222023  2024 
ANJ, 14 Sep 2022 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·