added more timeout handling code
This commit is contained in:
parent
0eb177db96
commit
d6c8bd4a1b
@ -277,6 +277,27 @@ BEGIN {
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
You can specify TCP or UDP timeouts for connection, accepting, reading, and
|
||||||
|
writing with setioattr (pipe-name, timeout-name, timeout-value). timeout-name
|
||||||
|
should be one of "ctimeout", "atimeout", "rtimeout", and "wtimeout".
|
||||||
|
timeout-value is a number specifying the actual timeout in milliseconds.
|
||||||
|
A negative value indicates no timeout.
|
||||||
|
|
||||||
|
You can call getioattr (pipe-name, timeout-name) to get the current
|
||||||
|
timeout-value set.
|
||||||
|
|
||||||
|
See the example below.
|
||||||
|
|
||||||
|
@code
|
||||||
|
BEGIN {
|
||||||
|
setioattr ("tcp://127.0.0.1:9999", "ctimeout", 3000);
|
||||||
|
setioattr ("tcp://127.0.0.1:9999", "rtimeout", 5000);
|
||||||
|
print "hello world" || "tcp://127.0.0.1:9999";
|
||||||
|
"tcp://127.0.0.1:9999" || getline x;
|
||||||
|
print x;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
@subsection awk_ext_return RETURN
|
@subsection awk_ext_return RETURN
|
||||||
The return statement is valid in BEGIN blocks, END blocks, and pattern-action
|
The return statement is valid in BEGIN blocks, END blocks, and pattern-action
|
||||||
blocks as well as in functions. The execution of a calling block is aborted
|
blocks as well as in functions. The execution of a calling block is aborted
|
||||||
|
@ -126,7 +126,7 @@ typedef struct ioattr_t
|
|||||||
{
|
{
|
||||||
qse_cmgr_t* cmgr;
|
qse_cmgr_t* cmgr;
|
||||||
qse_char_t cmgr_name[64]; /* i assume that the cmgr name never exceeds this length */
|
qse_char_t cmgr_name[64]; /* i assume that the cmgr name never exceeds this length */
|
||||||
qse_long_t tmout[4];
|
int tmout[4];
|
||||||
} ioattr_t;
|
} ioattr_t;
|
||||||
|
|
||||||
static ioattr_t* get_ioattr (qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len);
|
static ioattr_t* get_ioattr (qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len);
|
||||||
@ -1849,6 +1849,12 @@ static int fnc_setioattr (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
|||||||
x = qse_awk_rtx_strtonum (rtx, 0, ptr[2], len[2], &l, &r);
|
x = qse_awk_rtx_strtonum (rtx, 0, ptr[2], len[2], &l, &r);
|
||||||
if (x >= 1) l = (qse_long_t)r;
|
if (x >= 1) l = (qse_long_t)r;
|
||||||
|
|
||||||
|
if (l < QSE_TYPE_MIN(int) || l > QSE_TYPE_MAX(int))
|
||||||
|
{
|
||||||
|
fret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
pair = find_or_make_ioattr (rtx, &rxtn->cmgrtab, ptr[0], len[0]);
|
pair = find_or_make_ioattr (rtx, &rxtn->cmgrtab, ptr[0], len[0]);
|
||||||
if (pair == QSE_NULL)
|
if (pair == QSE_NULL)
|
||||||
{
|
{
|
||||||
|
@ -250,6 +250,36 @@ static qse_nwio_errnum_t tio_errnum_to_nwio_errnum (qse_tio_t* tio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wait_for_data (qse_nwio_t* nwio, int tmout, int what)
|
||||||
|
{
|
||||||
|
int xret;
|
||||||
|
fd_set fds[2];
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
FD_ZERO (&fds[0]);
|
||||||
|
FD_ZERO (&fds[1]);
|
||||||
|
|
||||||
|
FD_SET (nwio->handle, &fds[what]);
|
||||||
|
|
||||||
|
tv.tv_sec = tmout / QSE_MSECS_PER_SEC;
|
||||||
|
tv.tv_usec = (tmout % QSE_MSECS_PER_SEC) *
|
||||||
|
QSE_USECS_PER_MSEC;
|
||||||
|
|
||||||
|
xret = select (nwio->handle + 1, &fds[0], &fds[1], QSE_NULL, &tv);
|
||||||
|
if (xret <= -1)
|
||||||
|
{
|
||||||
|
nwio->errnum = syserr_to_errnum (errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (xret == 0)
|
||||||
|
{
|
||||||
|
nwio->errnum = QSE_NWIO_ETMOUT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
qse_nwio_t* qse_nwio_open (
|
qse_nwio_t* qse_nwio_open (
|
||||||
qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_nwad_t* nwad,
|
qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_nwad_t* nwad,
|
||||||
int flags, const qse_nwio_tmout_t* tmout)
|
int flags, const qse_nwio_tmout_t* tmout)
|
||||||
@ -499,6 +529,9 @@ int qse_nwio_init (
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nwio->tmout.a >= 0 &&
|
||||||
|
wait_for_data (nwio, nwio->tmout.a, 0) <= -1) goto oops;
|
||||||
|
|
||||||
handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
|
handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
|
||||||
if (handle <= -1)
|
if (handle <= -1)
|
||||||
{
|
{
|
||||||
@ -533,9 +566,6 @@ int qse_nwio_init (
|
|||||||
|
|
||||||
if (nwio->tmout.c >= 0 && (flags & QSE_NWIO_TCP))
|
if (nwio->tmout.c >= 0 && (flags & QSE_NWIO_TCP))
|
||||||
{
|
{
|
||||||
fd_set wfds;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
if ((xret <= -1 && errno != EINPROGRESS) ||
|
if ((xret <= -1 && errno != EINPROGRESS) ||
|
||||||
fcntl (nwio->handle, F_SETFL, orgfl) <= -1)
|
fcntl (nwio->handle, F_SETFL, orgfl) <= -1)
|
||||||
{
|
{
|
||||||
@ -543,29 +573,7 @@ int qse_nwio_init (
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_ZERO (&wfds);
|
if (wait_for_data (nwio, nwio->tmout.c, 1) <= -1) goto oops;
|
||||||
FD_SET (nwio->handle, &wfds);
|
|
||||||
tv.tv_sec = nwio->tmout.c / QSE_MSECS_PER_SEC;
|
|
||||||
tv.tv_usec = (nwio->tmout.c % QSE_MSECS_PER_SEC) *
|
|
||||||
QSE_USECS_PER_MSEC;
|
|
||||||
|
|
||||||
xret = select (nwio->handle + 1,
|
|
||||||
QSE_NULL, &wfds, QSE_NULL, &tv);
|
|
||||||
if (xret <= -1)
|
|
||||||
{
|
|
||||||
nwio->errnum = syserr_to_errnum (errno);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
else if (xret == 0)
|
|
||||||
{
|
|
||||||
nwio->errnum = QSE_NWIO_ETMOUT;
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
else if (!FD_ISSET (nwio->handle, &wfds))
|
|
||||||
{
|
|
||||||
nwio->errnum = QSE_NWIO_ECONN;
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(HAVE_SOCKLEN_T)
|
#if defined(HAVE_SOCKLEN_T)
|
||||||
@ -573,6 +581,7 @@ int qse_nwio_init (
|
|||||||
#else
|
#else
|
||||||
int xlen;
|
int xlen;
|
||||||
#endif
|
#endif
|
||||||
|
xlen = QSE_SIZEOF(xret);
|
||||||
if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xret, &xlen) <= -1)
|
if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xret, &xlen) <= -1)
|
||||||
{
|
{
|
||||||
nwio->errnum = syserr_to_errnum (errno);
|
nwio->errnum = syserr_to_errnum (errno);
|
||||||
@ -724,33 +733,6 @@ void qse_nwio_purge (qse_nwio_t* nwio)
|
|||||||
if (nwio->tio) qse_tio_purge (nwio->tio);
|
if (nwio->tio) qse_tio_purge (nwio->tio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_for_data (qse_nwio_t* nwio, int tmout, int what)
|
|
||||||
{
|
|
||||||
int xret;
|
|
||||||
fd_set fds[2];
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
FD_ZERO (&fds[0]);
|
|
||||||
FD_ZERO (&fds[1]);
|
|
||||||
FD_SET (nwio->handle, &fds[what]);
|
|
||||||
tv.tv_sec = tmout / QSE_MSECS_PER_SEC;
|
|
||||||
tv.tv_usec = (tmout % QSE_MSECS_PER_SEC) *
|
|
||||||
QSE_USECS_PER_MSEC;
|
|
||||||
|
|
||||||
xret = select (nwio->handle + 1, &fds[0], &fds[1], QSE_NULL, &tv);
|
|
||||||
if (xret <= -1)
|
|
||||||
{
|
|
||||||
nwio->errnum = syserr_to_errnum (errno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (xret == 0)
|
|
||||||
{
|
|
||||||
nwio->errnum = QSE_NWIO_ETMOUT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
|
static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
|
||||||
@ -860,10 +842,15 @@ reread:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
addrlen = QSE_SIZEOF(addr);
|
addrlen = QSE_SIZEOF(addr);
|
||||||
/* it's similar to accept for tcp.
|
|
||||||
* since i'm expecting the first sender and call
|
/* it's similar to accept for tcp because i'm expecting
|
||||||
* connect() to it below.
|
* the first sender and call connect() to it below just
|
||||||
* TODO: do i have apply tmout.a instead of tmout.r??? */
|
* like the 'nc' utility does.
|
||||||
|
* so i treat this recvfrom() as if it is accept().
|
||||||
|
*/
|
||||||
|
if (nwio->tmout.a >= 0 &&
|
||||||
|
wait_for_data (nwio, nwio->tmout.a, 0) <= -1) return -1;
|
||||||
|
|
||||||
n = recvfrom (
|
n = recvfrom (
|
||||||
nwio->handle, buf, size, 0,
|
nwio->handle, buf, size, 0,
|
||||||
(struct sockaddr*)&addr, &addrlen);
|
(struct sockaddr*)&addr, &addrlen);
|
||||||
@ -894,10 +881,8 @@ reread:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (nwio->tmout.r >= 0)
|
if (nwio->tmout.r >= 0 &&
|
||||||
{
|
wait_for_data (nwio, nwio->tmout.r, 0) <= -1) return -1;
|
||||||
if (wait_for_data (nwio, nwio->tmout.r, 0) <= -1) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = recv (nwio->handle, buf, size, 0);
|
n = recv (nwio->handle, buf, size, 0);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
@ -977,6 +962,9 @@ static qse_ssize_t nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t si
|
|||||||
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t);
|
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t);
|
||||||
|
|
||||||
rewrite:
|
rewrite:
|
||||||
|
if (nwio->tmout.w >= 0 &&
|
||||||
|
wait_for_data (nwio, nwio->tmout.w, 1) <= -1) return -1;
|
||||||
|
|
||||||
n = send (nwio->handle, data, size, 0);
|
n = send (nwio->handle, data, size, 0);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
@ -999,7 +987,9 @@ rewrite:
|
|||||||
qse_ssize_t qse_nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t size)
|
qse_ssize_t qse_nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t size)
|
||||||
{
|
{
|
||||||
if (nwio->tio == QSE_NULL)
|
if (nwio->tio == QSE_NULL)
|
||||||
|
{
|
||||||
return nwio_write (nwio, data, size);
|
return nwio_write (nwio, data, size);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user