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  2022  <20232024  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  <20232024 
<== Date ==> <== Thread ==>

Subject: Re: asynInterposeEos/StreamDevice: "read from low-level driver returned 1" and EAGAIN/EWOULDBLOCK
From: Érico Nogueira Rolim via Tech-talk <tech-talk at aps.anl.gov>
To: Mark Rivers <rivers at cars.uchicago.edu>, "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Date: Tue, 18 Apr 2023 18:48:20 +0000
Hi Mark,

It took me a bit, things have been quite hectic here ^-^

If anyone would like to follow these, I opened the issues below:


Cheers,
Érico

On 05/04/2023 18:35, Mark Rivers wrote:

Hi Erico,

 

Could I ask you to create Github issues for these? https://github.com/epics-modules/asyn/issues

 

Thanks,

Mark

 

 

 

 

From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Érico Nogueira Rolim via Tech-talk
Sent: Wednesday, April 5, 2023 9:13 AM
To: tech-talk at aps.anl.gov
Subject: asynInterposeEos/StreamDevice: "read from low-level driver returned 1" and EAGAIN/EWOULDBLOCK

 

Hi!

 

I am assisting with development of an IOC for a custom device that speaks SCPI over TCP, using StreamDevice and drvAsynIPPortConfigure. We were investigating how to detect that the device had been disconnected or turned off, for which we found a solution by using an asynRecord, along with the disconnectOnReadTimeout option, as suggested in [1].

 

However, while debugging these options, we enabled WARNINGS with asynSetTraceMask for our port, and were faced with the following warning:

 

2023/04/04 17:32:32.122 BPMRFFE read from low-level driver returned 1

 

Investigating this warning message, I found it belonged to the asynInterposeEos interface, which I understand is what StreamDevice uses to handle its InTerminator.

 

For a better picture of our setup, the protocol file contains:

 

OutTerminator

= CR LF; InTerminator

= CR LF;

inPIDTdAC

{ out

"GET:PID:Td:AC?"; in

"%f"; }

And the IOC running under strace (with some filtering enabled) looked like:

 

[pid

1310] poll([{fd=4, events=POLLOUT}], 1, 100) = 1 ([{fd=4, revents=POLLOUT}])  [pid

1310] sendto(4, "GET:PID:Td:AC?\r\n", 16, 0, NULL, 0) = 16 [pid

1310] poll([{fd=4, events=POLLIN}], 1, 1000) = 1 ([{fd=4, revents=POLLIN}])  [pid

1310] recvfrom(4, "0", 2048, 0, NULL, NULL) = 1 [pid

1310] poll([{fd=4, events=POLLIN}], 1, 100) = 1 ([{fd=4, revents=POLLIN}])  [pid

1310] recvfrom(4, "\r\n", 2048, 0, NULL, NULL) = 2 [pid

1310] poll([{fd=4, events=POLLIN}], 1, 1) = 0 (Timeout) [pid

1310] recvfrom(4, 0x561122ff95f0, 2048, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)

2023/04/04

17:32:32.122 BPMRFFE read from low-level driver returned 1

 

In reading back the strace, we realized a few things:

- The drvAsynIPPort code called recv() even when poll() returned a timeout, which seems non-ideal. However, looking at the code [2], it would seem to have been done to simplify the case for systems that don't support poll (nor select, seeing as asyn includes an emulation of poll based on select). Is that correct?

- The conditional in [3] is used to determine if we should disconnect from the device. It seems to rely on EWOULDBLOCK being the same as EAGAIN (since recv/recvfrom can return either of them [4]), which is not a guarantee -- though I don't know if it's actually the case for any platform. I wouldn't be surprised if a lot of code (in general and EPICS code specifically) relies on this assumption, but the Linux manuals recommend against it explicitly as well [5] (under ERRORS).

- asynInterposeEos's readIt is calling the underlying IPPort's read() function even though it should have matched with the end of string already (rereading [6] made me realize this happens because of StreamDevice's input flushing); this makes it so it returns asynTimeout to StreamDevice, which I assume deals with it just fine. However, since it's flushing the input with pasynUser->timeout=0, does it make sense for the "read from low-level driver returned 1" message to be a warning? It can easily pollute the warning output if one has a lot of SCAN records... Perhaps the message can be disabled or turned into an ASYN_TRACE_FLOW if pasynUser->timeout==0 && status==asynTimeout ?

 

[1] https://epics.anl.gov/tech-talk/2019/msg00297.php

[2] https://github.com/epics-modules/asyn/blob/891c1f17860a82603eeceb84767975e8dd005218/asyn/drvAsynSerial/drvAsynIPPort.c#L758

[3] https://github.com/epics-modules/asyn/blob/891c1f17860a82603eeceb84767975e8dd005218/asyn/drvAsynSerial/drvAsynIPPort.c#L799

[4] https://pubs.opengroup.org/onlinepubs/007904875/functions/recvfrom.html

[5] https://man7.org/linux/man-pages/man2/recv.2.html

[6] https://epics-modules.github.io/master/asyn/R4-35/RELEASE_NOTES.html

 

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.



References:
asynInterposeEos/StreamDevice: "read from low-level driver returned 1" and EAGAIN/EWOULDBLOCK Érico Nogueira Rolim via Tech-talk
RE: asynInterposeEos/StreamDevice: "read from low-level driver returned 1" and EAGAIN/EWOULDBLOCK Mark Rivers via Tech-talk

Navigate by Date:
Prev: Re: Sequencer configuration file Andrew Johnson via Tech-talk
Next: Motion Controls Engineer position at ALS in LBNL Miroslaw Dach 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  2022  <20232024 
Navigate by Thread:
Prev: RE: asynInterposeEos/StreamDevice: "read from low-level driver returned 1" and EAGAIN/EWOULDBLOCK Mark Rivers via Tech-talk
Next: base 7.0.7 build fails on RHEL7 Pearson, Matthew 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  2022  <20232024 
ANJ, 18 Apr 2023 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·