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 <2022> 2023 2024 2025 | 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 <2022> 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | RE: How to safely implement an asynPortDriver with SCAN records |
From: | Mark Rivers via Tech-talk <tech-talk at aps.anl.gov> |
To: | Érico Nogueira Rolim <erico.rolim at lnls.br> |
Cc: | tech-talk <tech-talk at aps.anl.gov> |
Date: | Fri, 8 Jul 2022 15:23:31 +0000 |
Hi Érico, The asynPort driver base class does not have an exit handler to destroy itself when the IOC is exiting, that is left to derived classes. Does your derived class establish
an exit handler with epicsAtExit? What leads you to believe that the asynPortDriver destructor is being called? Can you send the actual error trace when the IOC exits? I just tested with the asyn test applications "testErrors". That test application uses asynPortDriver. I modified asyn/iocBoot/ioctestErrors/st.cmd to have these lines
uncommented: dbLoadRecords("../../db/testErrors.db", "P=testErrors:,PORT=PORT1,ADDR=0,TIMEOUT=1,TSE=0,SCAN=.1 second,FIFO=0") dbLoadRecords("../../db/testErrorsInt64.db","P=testErrors:,PORT=PORT1,ADDR=0,TIMEOUT=1,TSE=0,SCAN=.1 second,FIFO=0") That causes the input records to periodically process at 0.1 second scan time. I have attached a screen shot of the medm screen which shows all of the input records
are scanning at 0.1 second. This is what I see when the IOC exits: iocRun: All initialization complete epics> exit corvette:asyn/iocBoot/ioctestErrors> So there are no errors when I exit the IOC. I have tried this a number of times and never see an error. Mark -----Original Message----- Hi! I have a custom class that inherits from asynPortDriver, but it also overrides the readUInt32Digital, readInt32 and readFloat64 methods, such that they read values from hardware to provide up to date information. Most of our records
for this IOC use SCAN set to I/O Intr, and we update values read from hardware when processing writes into hardware. However, we have some records for which we needed to use periodical SCAN ('0.1 second', in this case), due to their monitoring purpose, and
they use the aforementioned read* methods to obtain values from hardware. Unfortunately, when the IOC is exited (with 'exit' in the IOC shell, for example), it seems our asynPortDriver is destroyed before the thread responsible for the record updates is. This leads to multiple use-after-free issues during
IOC exit; they can be seen with pthread_mutex_* functions returning EINVAL, and sometimes triggering assertions in our backend. What is the recommended way forward here? Having things misbehave during exit is not the worst that could happen, but it's still an issue. The alternative I can see is adding a thread that polls through these HW values and using I/O
Intr for the records. I think this would always work, but it feels ugly, given that Epics already has periodical SCAN functionality. Thank you, Érico 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. |
Attachment:
testErrors.png
Description: testErrors.png