Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with long timeouts in TCP connect() #210

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions asyn/asynDriver/asynDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,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 @@ -313,6 +313,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 @@ -370,6 +371,7 @@ static asynManager manager = {
isEnabled,
isAutoConnect,
setAutoConnectTimeout,
getAutoConnectTimeout,
waitConnect,
registerInterruptSource,
getInterruptPvt,
Expand Down Expand Up @@ -2222,6 +2224,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
15 changes: 15 additions & 0 deletions asyn/drvAsynSerial/drvAsynIPPort.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,18 @@ connectIt(void *drvPvt, asynUser *pasynUser)
* problem is just that the device has DHCP'd itself an new number.
*/
if (tty->socketType != SOCK_DGRAM) {
double connectTimeout;
struct timeval saveTV, connectTV;
socklen_t svlen = sizeof saveTV;
pasynManager->getAutoConnectTimeout(&connectTimeout);
connectTV.tv_sec = (long)connectTimeout;
connectTV.tv_usec = (long)((connectTimeout - connectTV.tv_sec)*1000000);
if (getsockopt (fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&saveTV, &svlen) < 0) {
asynPrint(pasynUser, ASYN_TRACE_ERROR, "connectIt, error calling getsockopt for SO_RECVTIMEO: %s\n", strerror(SOCKERRNO));
}
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&connectTV, sizeof connectTV) < 0) {
asynPrint(pasynUser, ASYN_TRACE_ERROR, "connectIt, error calling setsockopt for SO_RECVTIMEO: %s\n", strerror(SOCKERRNO));
}
if (connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize) < 0) {
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't connect to %s: %s",
Expand All @@ -520,6 +532,9 @@ connectIt(void *drvPvt, asynUser *pasynUser)
tty->flags |= FLAG_NEED_LOOKUP;
return asynError;
}
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&saveTV, sizeof saveTV) < 0) {
asynPrint(pasynUser, ASYN_TRACE_ERROR, "connectIt, error calling setsockopt for SO_RECVTIMEO: %s\n", strerror(SOCKERRNO));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All 3 error messages are using the wrong option name (RECV instead of SND).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed that, thanks for catching it.

}
}
}
i = 1;
Expand Down
Loading