Index: ossp-pkg/sa/sa.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.c,v rcsdiff -q -kk '-r1.9' '-r1.10' -u '/v/ossp/cvs/ossp-pkg/sa/sa.c,v' 2>/dev/null --- sa.c 2001/10/06 16:01:48 1.9 +++ sa.c 2001/10/07 14:16:47 1.10 @@ -63,8 +63,7 @@ struct sa_st { sa_type_t eType; /* socket type (stream or datagram) */ int fdSocket; /* socket file descriptor */ - int bTimeout; /* timeout enabling flag */ - struct timeval tvTimeout; /* timeout value (sec, usec) */ + struct timeval tvTimeout[6];/* timeout values (sec, usec) */ int nReadLen; /* read buffer current length */ int nReadSize; /* read buffer current size */ char *cpReadBuf; /* read buffer memory chunk */ @@ -84,6 +83,10 @@ #define TRUE (!FALSE) #endif +/* handy struct timeval check */ +#define SA_TVISZERO(tv) \ + ((tv).tv_sec == 0 && (tv).tv_usec == 0) + /* backward compatibility for AF_LOCAL */ #if !defined(AF_LOCAL) && defined(AF_UNIX) #define AF_LOCAL AF_UNIX @@ -669,6 +672,7 @@ sa_rc_t sa_create(sa_t **sap) { sa_t *sa; + int i; /* argument sanity check(s) */ if (sap == NULL) @@ -679,9 +683,10 @@ return SA_ERR_MEM; sa->eType = SA_TYPE_STREAM; sa->fdSocket = -1; - sa->bTimeout = FALSE; - sa->tvTimeout.tv_sec = 0; - sa->tvTimeout.tv_usec = 0; + for (i = 0; i < (sizeof(sa->tvTimeout)/sizeof(sa->tvTimeout[0])); i++) { + sa->tvTimeout[i].tv_sec = 0; + sa->tvTimeout[i].tv_usec = 0; + } sa->nReadLen = 0; sa->nReadSize = 0; sa->cpReadBuf = NULL; @@ -738,19 +743,24 @@ } /* configure I/O timeout */ -sa_rc_t sa_timeout(sa_t *sa, long sec, long usec) +sa_rc_t sa_timeout(sa_t *sa, sa_timeout_t id, long sec, long usec) { + int i; + /* argument sanity check(s) */ if (sa == NULL) return SA_ERR_ARG; - /* configure timeout */ - if (sec == 0 && usec == 0) - sa->bTimeout = FALSE; /* deactivate timeout */ - else - sa->bTimeout = TRUE; /* activate timeout */ - sa->tvTimeout.tv_sec = sec; - sa->tvTimeout.tv_usec = usec; + if (id == SA_TIMEOUT_ALL) { + for (i = 0; i < (sizeof(sa->tvTimeout)/sizeof(sa->tvTimeout[0])); i++) { + sa->tvTimeout[i].tv_sec = sec; + sa->tvTimeout[i].tv_usec = usec; + } + } + else { + sa->tvTimeout[id].tv_sec = sec; + sa->tvTimeout[id].tv_usec = usec; + } return SA_OK; } @@ -857,7 +867,7 @@ return rv; rv = SA_OK; - if (!sa->bTimeout) { + if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) { /* standard/non-timeout-aware connect operation */ if (connect(sa->fdSocket, raddr->saBuf, raddr->slBuf) < 0) rv = SA_ERR_SYS; @@ -888,7 +898,8 @@ FD_SET(sa->fdSocket, &rset); FD_SET(sa->fdSocket, &wset); do { - n = select(sa->fdSocket+1, &rset, &wset, NULL, &sa->tvTimeout); + n = select(sa->fdSocket+1, &rset, &wset, NULL, + &sa->tvTimeout[SA_TIMEOUT_CONNECT]); } while (n == -1 && errno == EINTR); /* decide on return semantic */ @@ -970,11 +981,12 @@ return SA_ERR_USE; /* if timeout is enabled, perform a smart-blocking wait */ - if (sa->bTimeout) { + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_ACCEPT])) { FD_ZERO(&fds); FD_SET(sa->fdSocket, &fds); do { - n = select(sa->fdSocket+1, &fds, NULL, NULL, &sa->tvTimeout); + n = select(sa->fdSocket+1, &fds, NULL, NULL, + &sa->tvTimeout[SA_TIMEOUT_ACCEPT]); } while (n == -1 && errno == EINTR); if (n == 0) errno = ETIMEDOUT; @@ -1106,11 +1118,12 @@ /* if timeout is enabled, perform explicit/smart blocking instead of implicitly/hard blocking in the read(2) system call */ - if (sa->bTimeout) { + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) { FD_ZERO(&fds); FD_SET(sa->fdSocket, &fds); do { - rv = select(sa->fdSocket+1, &fds, NULL, NULL, &sa->tvTimeout); + rv = select(sa->fdSocket+1, &fds, NULL, NULL, + &sa->tvTimeout[SA_TIMEOUT_READ]); } while (rv == -1 && errno == EINTR); if (rv == 0) { errno = ETIMEDOUT; @@ -1264,11 +1277,12 @@ /* if timeout is enabled, perform explicit/smart blocking instead of implicitly/hard blocking in the write(2) system call */ - if (sa->bTimeout) { + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) { FD_ZERO(&fds); FD_SET(sa->fdSocket, &fds); do { - rv = select(sa->fdSocket+1, NULL, &fds, NULL, &sa->tvTimeout); + rv = select(sa->fdSocket+1, NULL, &fds, NULL, + &sa->tvTimeout[SA_TIMEOUT_WRITE]); } while (rv == -1 && errno == EINTR); if (rv == 0) { errno = ETIMEDOUT; @@ -1474,11 +1488,12 @@ /* if timeout is enabled, perform explicit/smart blocking instead of implicitly/hard blocking in the recvfrom(2) system call */ - if (sa->bTimeout) { + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_RECV])) { FD_ZERO(&fds); FD_SET(sa->fdSocket, &fds); do { - n = select(sa->fdSocket+1, &fds, NULL, NULL, &sa->tvTimeout); + n = select(sa->fdSocket+1, &fds, NULL, NULL, + &sa->tvTimeout[SA_TIMEOUT_RECV]); } while (n == -1 && errno == EINTR); if (n == 0) errno = ETIMEDOUT; @@ -1529,11 +1544,12 @@ /* if timeout is enabled, perform explicit/smart blocking instead of implicitly/hard blocking in the sendto(2) system call */ - if (sa->bTimeout) { + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_SEND])) { FD_ZERO(&fds); FD_SET(sa->fdSocket, &fds); do { - n = select(sa->fdSocket+1, NULL, &fds, NULL, &sa->tvTimeout); + n = select(sa->fdSocket+1, NULL, &fds, NULL, + &sa->tvTimeout[SA_TIMEOUT_SEND]); } while (n == -1 && errno == EINTR); if (n == 0) errno = ETIMEDOUT; Index: ossp-pkg/sa/sa.h RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.h,v rcsdiff -q -kk '-r1.10' '-r1.11' -u '/v/ossp/cvs/ossp-pkg/sa/sa.h,v' 2>/dev/null --- sa.h 2001/10/06 16:01:48 1.10 +++ sa.h 2001/10/07 14:16:47 1.11 @@ -102,6 +102,17 @@ SA_ERR_INT /* internal error */ } sa_rc_t; +/* list of timeouts */ +typedef enum { + SA_TIMEOUT_ALL = -1, + SA_TIMEOUT_ACCEPT = 0, + SA_TIMEOUT_CONNECT = 1, + SA_TIMEOUT_READ = 2, + SA_TIMEOUT_WRITE = 3, + SA_TIMEOUT_RECV = 4, + SA_TIMEOUT_SEND = 5 +} sa_timeout_t; + /* error handling operations */ sa_rc_t sa_error (sa_t *sa, sa_rc_t rv, char **str); @@ -121,7 +132,7 @@ /* socket parameter operations */ sa_rc_t sa_type (sa_t *sa, sa_type_t type); -sa_rc_t sa_timeout (sa_t *sa, long sec, long usec); +sa_rc_t sa_timeout (sa_t *sa, sa_timeout_t id, long sec, long usec); sa_rc_t sa_buffers (sa_t *sa, size_t rsize, size_t wsize); /* socket connection operations */