Skip to content

Commit

Permalink
Merge f44ddc8 into d55786e
Browse files Browse the repository at this point in the history
  • Loading branch information
ericonr authored Dec 3, 2024
2 parents d55786e + f44ddc8 commit b8bbe39
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
1 change: 1 addition & 0 deletions asyn/asynDriver/asynDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ typedef struct asynManager {
asynStatus (*isEnabled)(asynUser *pasynUser,int *yesNo);
asynStatus (*isAutoConnect)(asynUser *pasynUser,int *yesNo);
asynStatus (*setAutoConnectTimeout)(double timeout);
asynStatus (*getAutoConnectTimeout)(double *timeout);
asynStatus (*waitConnect)(asynUser *pasynUser, double timeout);
/*The following are methods for interrupts*/
asynStatus (*registerInterruptSource)(const char *portName,
Expand Down
11 changes: 11 additions & 0 deletions asyn/asynDriver/asynManager.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ static asynStatus isConnected(asynUser *pasynUser,int *yesNo);
static asynStatus isEnabled(asynUser *pasynUser,int *yesNo);
static asynStatus isAutoConnect(asynUser *pasynUser,int *yesNo);
static asynStatus setAutoConnectTimeout(double timeout);
static asynStatus getAutoConnectTimeout(double *timeout);
static asynStatus waitConnect(asynUser *pasynUser, double timeout);
static asynStatus registerInterruptSource(const char *portName,
asynInterface *pasynInterface, void **pasynPvt);
Expand Down Expand Up @@ -374,6 +375,7 @@ static asynManager manager = {
isEnabled,
isAutoConnect,
setAutoConnectTimeout,
getAutoConnectTimeout,
waitConnect,
registerInterruptSource,
getInterruptPvt,
Expand Down Expand Up @@ -2376,6 +2378,15 @@ static asynStatus setAutoConnectTimeout(double timeout)
return asynSuccess;
}

static asynStatus getAutoConnectTimeout(double *timeout)
{
if(!pasynBase) asynInit();
epicsMutexMustLock(pasynBase->lock);
*timeout = pasynBase->autoConnectTimeout;
epicsMutexUnlock(pasynBase->lock);
return asynSuccess;
}

static asynStatus setQueueLockPortTimeout(asynUser *pasynUser, double timeout)
{
userPvt *puserPvt = asynUserToUserPvt(pasynUser);
Expand Down
54 changes: 44 additions & 10 deletions asyn/drvAsynSerial/drvAsynIPPort.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,56 @@ connectIt(void *drvPvt, asynUser *pasynUser)
}
}

}

#ifdef USE_POLL
if (setNonBlock(fd, 1) < 0) {
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s O_NONBLOCK option: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
epicsSocketDestroy(fd);
return asynError;
}
#endif

if (pasynUser->reason <= 0) {

/*
* Connect to the remote host
* If the connect fails, arrange for another DNS lookup in case the
* problem is just that the device has DHCP'd itself an new number.
*/
if (tty->socketType != SOCK_DGRAM) {
if (connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize) < 0) {
int connectResult = connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize);
#ifdef USE_POLL
if (connectResult < 0 && ((SOCKERRNO == EWOULDBLOCK) || (SOCKERRNO == EINPROGRESS))) {
double connectTimeout;
int msConnectTimeout;
struct pollfd pollfd;

pasynManager->getAutoConnectTimeout(&connectTimeout);
msConnectTimeout = 1000 * connectTimeout;
pollfd.fd = fd;
pollfd.events = POLLOUT;

/*
* poll() returning 1 is the only case where connect might have been successful.
* Otherwise connectResult will remain -1.
*/
if (poll(&pollfd, 1, msConnectTimeout) == 1) {
int so_error;
socklen_t len = sizeof so_error;

/*
* We must verify SO_ERROR to make sure the connection was successful.
*/
getsockopt(fd, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error == 0)
connectResult = 0;
}
}
#endif
if (connectResult < 0) {
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't connect to %s: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
Expand All @@ -532,15 +575,6 @@ connectIt(void *drvPvt, asynUser *pasynUser)
epicsSocketDestroy(fd);
return asynError;
}
#ifdef USE_POLL
if (setNonBlock(fd, 1) < 0) {
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s O_NONBLOCK option: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
epicsSocketDestroy(fd);
return asynError;
}
#endif

asynPrint(pasynUser, ASYN_TRACE_FLOW,
"Opened connection OK to %s\n", tty->IPDeviceName);
Expand Down

0 comments on commit b8bbe39

Please sign in to comment.