* fhandler_socket.cc (fhandler_socket::send_internal): Send never more
then 64K bytes at once. For blocking sockets, loop until entire data has been sent or an error occurs. (fhandler_socket::sendto): Drop code which sends on 64K bytes. (fhandler_socket::sendmsg): Ditto.
This commit is contained in:
parent
34cc372abe
commit
bfd2b1c930
|
@ -1,3 +1,11 @@
|
||||||
|
2008-07-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_socket.cc (fhandler_socket::send_internal): Send never more
|
||||||
|
then 64K bytes at once. For blocking sockets, loop until entire data
|
||||||
|
has been sent or an error occurs.
|
||||||
|
(fhandler_socket::sendto): Drop code which sends on 64K bytes.
|
||||||
|
(fhandler_socket::sendmsg): Ditto.
|
||||||
|
|
||||||
2008-07-26 Christopher Faylor <me+cygwin@cgf.cx>
|
2008-07-26 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* fhandler_tty.cc (fhandler_pty_master::setup): Reorganize so that all
|
* fhandler_tty.cc (fhandler_pty_master::setup): Reorganize so that all
|
||||||
|
|
|
@ -1415,38 +1415,57 @@ fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
|
||||||
const struct sockaddr *to, int tolen)
|
const struct sockaddr *to, int tolen)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
DWORD ret = 0, err = 0;
|
DWORD ret = 0, err = 0, sum = 0, off = 0;
|
||||||
|
WSABUF buf;
|
||||||
|
|
||||||
do
|
for (DWORD i = 0; i < wsacnt; off >= wsabuf[i].len && (++i, off = 0))
|
||||||
{
|
{
|
||||||
if ((res = WSASendTo (get_socket (), wsabuf, wsacnt, &ret,
|
buf.buf = wsabuf[i].buf + off;
|
||||||
flags & (MSG_OOB | MSG_DONTROUTE), to, tolen, NULL, NULL))
|
buf.len = wsabuf[i].len - off;
|
||||||
&& (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
|
if (buf.len > 65536) /* See KB 823764 */
|
||||||
|
buf.len = 65536;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
LOCK_EVENTS;
|
if ((res = WSASendTo (get_socket (), &buf, 1, &ret,
|
||||||
wsock_events->events &= ~FD_WRITE;
|
flags & (MSG_OOB | MSG_DONTROUTE), to, tolen,
|
||||||
UNLOCK_EVENTS;
|
NULL, NULL))
|
||||||
|
&& (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
LOCK_EVENTS;
|
||||||
|
wsock_events->events &= ~FD_WRITE;
|
||||||
|
UNLOCK_EVENTS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
while (res && err == WSAEWOULDBLOCK
|
||||||
|
&& !(res = wait_for_events (FD_WRITE | FD_CLOSE)));
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
off += ret;
|
||||||
|
sum += ret;
|
||||||
|
}
|
||||||
|
else if (is_nonblocking () || err != WSAEWOULDBLOCK)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
while (res && err == WSAEWOULDBLOCK
|
|
||||||
&& !(res = wait_for_events (FD_WRITE | FD_CLOSE)));
|
if (sum)
|
||||||
|
res = sum;
|
||||||
if (res == SOCKET_ERROR)
|
else if (res == SOCKET_ERROR)
|
||||||
set_winsock_errno ();
|
|
||||||
else
|
|
||||||
res = ret;
|
|
||||||
|
|
||||||
/* Special handling for EPIPE and SIGPIPE.
|
|
||||||
|
|
||||||
EPIPE is generated if the local end has been shut down on a connection
|
|
||||||
oriented socket. In this case the process will also receive a SIGPIPE
|
|
||||||
unless MSG_NOSIGNAL is set. */
|
|
||||||
if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
|
|
||||||
&& get_socket_type () == SOCK_STREAM)
|
|
||||||
{
|
{
|
||||||
set_errno (EPIPE);
|
set_winsock_errno ();
|
||||||
if (! (flags & MSG_NOSIGNAL))
|
|
||||||
raise (SIGPIPE);
|
/* Special handling for EPIPE and SIGPIPE.
|
||||||
|
|
||||||
|
EPIPE is generated if the local end has been shut down on a connection
|
||||||
|
oriented socket. In this case the process will also receive a SIGPIPE
|
||||||
|
unless MSG_NOSIGNAL is set. */
|
||||||
|
if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM)
|
||||||
|
{
|
||||||
|
set_errno (EPIPE);
|
||||||
|
if (! (flags & MSG_NOSIGNAL))
|
||||||
|
raise (SIGPIPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -1467,7 +1486,7 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
|
||||||
the size of the internal send buffer. A buffer full condition
|
the size of the internal send buffer. A buffer full condition
|
||||||
is only recognized in subsequent calls and, if len is big enough,
|
is only recognized in subsequent calls and, if len is big enough,
|
||||||
the call even might fail with an out-of-memory condition. */
|
the call even might fail with an out-of-memory condition. */
|
||||||
WSABUF wsabuf = { len > 65536 ? 65536 : len, (char *) ptr };
|
WSABUF wsabuf = { len, (char *) ptr };
|
||||||
return send_internal (&wsabuf, 1, flags,
|
return send_internal (&wsabuf, 1, flags,
|
||||||
(to ? (const struct sockaddr *) &sst : NULL), tolen);
|
(to ? (const struct sockaddr *) &sst : NULL), tolen);
|
||||||
}
|
}
|
||||||
|
@ -1487,14 +1506,9 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
|
||||||
WSABUF wsabuf[msg->msg_iovlen];
|
WSABUF wsabuf[msg->msg_iovlen];
|
||||||
WSABUF *wsaptr = wsabuf;
|
WSABUF *wsaptr = wsabuf;
|
||||||
const struct iovec *iovptr = msg->msg_iov;
|
const struct iovec *iovptr = msg->msg_iov;
|
||||||
size_t total = 0;
|
for (int i = 0; i < msg->msg_iovlen; ++i)
|
||||||
for (int i = 0; i < msg->msg_iovlen && total < 65536; ++i)
|
|
||||||
{
|
{
|
||||||
if (total + iovptr->iov_len > 65536) /* See above. */
|
wsaptr->len = iovptr->iov_len;
|
||||||
wsaptr->len = 65536 - total;
|
|
||||||
else
|
|
||||||
wsaptr->len = iovptr->iov_len;
|
|
||||||
total += wsaptr->len;
|
|
||||||
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
(wsaptr++)->buf = (char *) (iovptr++)->iov_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue