* fhandler.h (class fhandler_socket): Add class members and methods

to store and retrieve the SO_RCVBUF and SO_SNDBUF sizes.
	* fhandler_socket.cc (fhandler_socket::dup): Duplicate new members.
	(fhandler_socket::send_internal): Check for SO_SNDBUF size and
	restrict send to 1 byte less per KB 823764.  Leave loop immediately
	if WSASendMsg has been used.
	* net.cc (fdsock): Change comment again.  Set buffer sizes to 65536.
	Store values in fhandler_socket.
	(cygwin_setsockopt): Store SO_RCVBUF and SO_SNDBUF sizes in
	fhandler_socket.
	(cygwin_sendto): Drop call to sig_dispatch_pending.
	(cygwin_recvfrom): Ditto.
	(cygwin_recvmsg): Ditto.
	(cygwin_sendmsg): Ditto.
This commit is contained in:
Corinna Vinschen 2009-07-01 09:16:17 +00:00
parent b4fa816474
commit 975a630109
4 changed files with 68 additions and 17 deletions

View File

@ -1,3 +1,20 @@
2009-07-01 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_socket): Add class members and methods
to store and retrieve the SO_RCVBUF and SO_SNDBUF sizes.
* fhandler_socket.cc (fhandler_socket::dup): Duplicate new members.
(fhandler_socket::send_internal): Check for SO_SNDBUF size and
restrict send to 1 byte less per KB 823764. Leave loop immediately
if WSASendMsg has been used.
* net.cc (fdsock): Change comment again. Set buffer sizes to 65536.
Store values in fhandler_socket.
(cygwin_setsockopt): Store SO_RCVBUF and SO_SNDBUF sizes in
fhandler_socket.
(cygwin_sendto): Drop call to sig_dispatch_pending.
(cygwin_recvfrom): Ditto.
(cygwin_recvmsg): Ditto.
(cygwin_sendmsg): Ditto.
2009-06-30 Christopher Faylor <me+cygwin@cgf.cx>
* select.h: New file split from fhandler.h.

View File

@ -445,6 +445,15 @@ class fhandler_socket: public fhandler_base
int af_local_connect ();
void af_local_set_sockpair_cred ();
private:
int _rmem;
int _wmem;
public:
int &rmem () { return _rmem; }
int &wmem () { return _wmem; }
void rmem (int nrmem) { _rmem = nrmem; }
void wmem (int nwmem) { _wmem = nwmem; }
private:
char *sun_path;
struct status_flags

View File

@ -657,6 +657,8 @@ fhandler_socket::dup (fhandler_base *child)
}
fhs->wsock_events = wsock_events;
fhs->rmem (rmem ());
fhs->wmem (wmem ());
fhs->addr_family = addr_family;
fhs->set_socket_type (get_socket_type ());
if (get_addr_family () == AF_LOCAL)
@ -1486,11 +1488,16 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
use_sendmsg = true;
for (DWORD i = 0; i < wsamsg->dwBufferCount;
off >= wsamsg->lpBuffers[i].len && (++i, off = 0))
{
/* FIXME? Use the same technique in call to WSASendMsg? */
if (!use_sendmsg)
{
buf.buf = wsamsg->lpBuffers[i].buf + off;
buf.len = wsamsg->lpBuffers[i].len - off;
if (buf.len > 65520) /* See net.cc:fdsock() and MSDN KB 823764 */
buf.len = 65520;
/* See net.cc:fdsock() and MSDN KB 823764 */
if (buf.len >= (unsigned) wmem ())
buf.len = (unsigned) wmem () - 1;
}
do
{
@ -1513,6 +1520,8 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
{
off += ret;
sum += ret;
if (use_sendmsg)
break;
}
else if (is_nonblocking () || err != WSAEWOULDBLOCK)
break;

View File

@ -495,18 +495,25 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
/* Raise default buffer sizes (instead of WinSock default 8K).
64K appear to have the best size/performance ratio for a default
value. Tested with ssh/scp on Vista over Gigabit LAN.
NOTE. If the SO_RCVBUF size exceeds 65535(*), and if the socket is
connected to a remote machine, then duplicating the socket on fork/exec
fails with WinSock error 10022, WSAEINVAL. An explanation for this
weird behaviour would be nice.
connected to a remote machine, then calling WSADuplicateSocket on
fork/exec fails with WinSock error 10022, WSAEINVAL. Fortunately
we don't use WSADuplicateSocket anymore, rather we just utilize
handle inheritance. An explanation for this weird behaviour would
be nice, though.
(*) Maximum normal TCP window size. Coincidence? */
int rmem = 65520;
int wmem = 65520;
if (::setsockopt (soc, SOL_SOCKET, SO_RCVBUF, (char *) &rmem, sizeof (int)))
((fhandler_socket *) fd)->rmem () = 65536;
((fhandler_socket *) fd)->wmem () = 65536;
if (::setsockopt (soc, SOL_SOCKET, SO_RCVBUF,
(char *) &((fhandler_socket *) fd)->rmem (), sizeof (int)))
debug_printf ("setsockopt(SO_RCVBUF) failed, %lu", WSAGetLastError ());
if (::setsockopt (soc, SOL_SOCKET, SO_SNDBUF, (char *) &wmem, sizeof (int)))
if (::setsockopt (soc, SOL_SOCKET, SO_SNDBUF,
(char *) &((fhandler_socket *) fd)->wmem (), sizeof (int)))
debug_printf ("setsockopt(SO_SNDBUF) failed, %lu", WSAGetLastError ());
return true;
@ -560,7 +567,6 @@ cygwin_sendto (int fd, const void *buf, size_t len, int flags,
const struct sockaddr *to, socklen_t tolen)
{
int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd);
@ -582,7 +588,6 @@ cygwin_recvfrom (int fd, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd);
@ -683,8 +688,21 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
else
set_winsock_errno ();
}
else if (level == SOL_SOCKET && optname == SO_REUSEADDR)
else if (level == SOL_SOCKET)
switch (optname)
{
case SO_REUSEADDR:
fh->saw_reuseaddr (*(int *) optval);
break;
case SO_RCVBUF:
fh->rmem (*(int *) optval);
break;
case SO_SNDBUF:
fh->wmem (*(int *) optval);
break;
default:
break;
}
}
syscall_printf ("%d = setsockopt (%d, %d, %x, %p, %d)",
@ -2901,7 +2919,6 @@ extern "C" int
cygwin_recvmsg (int fd, struct msghdr *msg, int flags)
{
int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd);
@ -2924,7 +2941,6 @@ extern "C" int
cygwin_sendmsg (int fd, const struct msghdr *msg, int flags)
{
int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd);