Yes.
asynManager provides the following methods that are used use for connection management:
asynStatus (*exceptionConnect)(asynUser *pasynUser);
asynStatus (*exceptionDisconnect)(asynUser *pasynUser);
asynStatus (*autoConnect)(asynUser *pasynUser,int yesNo);
asynStatus (*isConnected)(asynUser *pasynUser,int *yesNo);
asynStatus (*isAutoConnect)(asynUser *pasynUser,int *yesNo);
Those are documented here:
The asynCommon interface provides the following methods that asynManager and asyn clients use for connection management:
typedef struct asynCommon {
...
asynStatus (*connect)(void *drvPvt,asynUser *pasynUser);
asynStatus (*disconnect)(void *drvPvt,asynUser *pasynUser);
}asynCommon;
These methods must be implemented by all drivers. They are documented here:
It is always good practice to load an asyn record for each port. That provides the following PVs:
Name
|
Access
|
Prompt
|
Data type
|
Description
|
AUCT
|
R/W
|
“Autoconnect”
|
DBF_MENU
|
Sets the autoconnect option. Choices are “noAutoConnect” and “autoConnect”. The value read reflects current state of the autoconnect flag, i.e. the value returned from isAutoConnect().
|
ENBL
|
R/W
|
“Disable/Enable”
|
DBF_MENU
|
Disables or enables the port. Choices are “Disable” and “Enable”. The value read reflects current state of the enabled flag, i.e. the value returned from isEnabled().
|
CNCT
|
R/W
|
“Connect/Disconnect”
|
DBF_MENU
|
Disconnects or connects the device. Choices are “Disconnect” and “Connect”. The value read reflects current state of the connected flag, i.e. the value returned from isConnected().
|
Those are documented here:
The asyn TCP driver (drvAsynIPPort) implements connection management. It connects (opens the socket) when the pasynCommon->connect() method is called. If the socket open is successful, then the driver calls pasynManager->exceptionConnect to indicate that
it is connected. If isAutoConnect is true then asynManager will call this method when the port is created, and whenever it is disconnected and a client queues an I/O request. If isAutoConnect is false then pasynCommon->connect() method must be called by
the client. Whenever the driver detects that the socket is disconnected it calls pasynManager->exceptionDisconnect to indicate that state.
It can take a long time for the OS to close a socket for a non-responsive device, and I/O operations only return the disconnected status once that happens. The asynOption disconnectOnReadTimeout can be used to force the driver to disconnect whenever an I/O
operation times out. Michael Davidsaver has asked whether that should be the default behavior. I would be interested to hear whether that would be acceptable, or would break expected behavior.
Mark
From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Dmitry Yu. Bolkhovityanov via Tech-talk <tech-talk at aps.anl.gov>
Sent: Sunday, September 21, 2025 2:39 AM
To: Michael Davidsaver <mdavidsaver at gmail.com>
Cc: EPICS Tech Talk <tech-talk at aps.anl.gov>
Subject: Re: Help with bumpless IOC reboot, record linking and initialization concepts
Hi Michael!
On Sat, 20 Sep 2025, Michael Davidsaver via Tech-talk wrote:
> On 9/19/25 00:35, Marco Filho wrote:
>> Ah, I think I didn't properly understand this email on the first read.
>>
>> > Generally, I have found that the more effective way to coordinate
>> > connect/disconnect is at the driver level. Generally with a special
>> > device support to drive on-connect processing.
IMHO, it isn't a "more effective" but is rather the ONLY reliable way.
As only the driver code, which issues a connect() call and is directly
notified about connect success or failure, thus has first-hand knowledge
of the connection status and is able to perform connect/disconnect.
All the other ways use some form of side effects, which are unreliable
and can change with time.
>> You mean disconnecting from the actual equipment before the PVs are
>> initialized and then only connecting once all the links are properly
>> initialized?
>> If so, how do you detect at driver level that that has happened?
>
> I think you have right idea, although the other way around. My thinking is
> that a driver initializes into a latched "error" state, which is cleared by
> processing a record. I like this approach because it naturally leads to
> handling the initial connection the same as a re-connect.
For me it seems obvious to use 2 boolean PVs:
1. "isConnected", which is SCAN="I/O intr" and is updated by the
driver upon change of connection state to be 1 (connected) or 0
(disconnected); initially value is 0. (It can be naturally
monitored by code and DB links; multiple "isConnected" values
can be ANDed).
2. "doConnect", which can be written to, =1 means "connect if not
connected" and =0 means "disconnect".
Isn't such a thing already done somewhere in asyn, streamDevice etc.?
|