Hi Garth,
asynManager only allows one I/O operation to a port to be occurring at the same time. These are the 3 ways that your code is allowed to do an I/O operation on the asynOctet interface:
1) Call pasynManager->queueRequest(), and then call pasynOctet->read(), pasynOctet->write(), etc. in the callback function.
2) Call pasynOctetSyncIO->write(), pasynOctetSyncIO->read(), pasynOctetSyncIO->writeRead(), etc.
3) Call pasynManager->lockPort() and then call pasynOctet->read(), pasynOctet->write(), etc., then call pasynManager->unlockPort().
If you are using the pasynOctetSyncIO functions then this is how you should write your read thread()
while (1) {
status = pasynOctetSyncIO->read(pasynUser, inpBuf, sizeof(inpBuf), TIMEOUT, &nRead, &eomReason);
if (status == asynSuccess) {
// process data
}
}
You should set TIMEOUT to a short value like 0.01 seconds. So you effectively polling to see if there is new input, while allowing your write thread to get access to the port.
Prior to asyn R4-14 the while loop above would have required a call to epicsThreadSleep() or else the read thread would effectively have exclusive access to the port, and the write thread would never get a chance to run. In R4-14 the pasynXXXSyncIO functions were changed so they queue their requests to lock the port. This means that the write thread can queue a request while the read thread is waiting for the I/O timeout, and it is no longer necessary to use epicsThreadSleep(). However, if instead of calling pasynOctetSyncIO functions you use the pasynManager->lockPort() and pasynManager->unlockPort() mechanism then you must make calls to epicsThreadSleep or you will effectively have exclusive access to the port. Alternatively you can call pasynManager->queueLockPort(), which is what the pasynXXXSyncIO functions do.
Mark
________________________________________
From: [email protected] [[email protected]] on behalf of Brown, Garth [[email protected]]
Sent: Thursday, July 14, 2016 7:24 PM
To: '[email protected]'
Subject: drvAsynIPPort, asynOctetSyncIO and multithreading
This seems like something that must have a well-known solution, but I haven't dug it up yet.
I'm working on an app talking to a network attached device. I want to allow multiple threads to send requests to the device, and have another thread that blocks waiting for responses to come back. There could be multiple outstanding requests, and there's no reason from my code's perspective that responses should come back in order.
My initial attempt uses pasynOctetSyncIO->write and pasynOctetSyncIO->read, but it looks like there's a mutex in asynOctetSyncIO writeIt and readIt functions that prevents writing while read is blocking. Is there a way to allow the "reading" thread to wait for responses that still allows writes to happen?
Thanks,
Garth
- References:
- drvAsynIPPort, asynOctetSyncIO and multithreading Brown, Garth
- Navigate by Date:
- Prev:
Re: EPICS archiver appliance redundancy Phillip Sorensen
- Next:
Re: EpicsQT and Archiver Appliance Michael Davidsaver
- 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
- Navigate by Thread:
- Prev:
drvAsynIPPort, asynOctetSyncIO and multithreading Brown, Garth
- Next:
CARS:Modbus - function 06 (write single register) issue Nick Levchenko
- 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
|