* 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> 2009-06-30 Christopher Faylor <me+cygwin@cgf.cx>
* select.h: New file split from fhandler.h. * select.h: New file split from fhandler.h.

View File

@ -445,6 +445,15 @@ class fhandler_socket: public fhandler_base
int af_local_connect (); int af_local_connect ();
void af_local_set_sockpair_cred (); 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: private:
char *sun_path; char *sun_path;
struct status_flags struct status_flags

View File

@ -657,6 +657,8 @@ fhandler_socket::dup (fhandler_base *child)
} }
fhs->wsock_events = wsock_events; fhs->wsock_events = wsock_events;
fhs->rmem (rmem ());
fhs->wmem (wmem ());
fhs->addr_family = addr_family; fhs->addr_family = addr_family;
fhs->set_socket_type (get_socket_type ()); fhs->set_socket_type (get_socket_type ());
if (get_addr_family () == AF_LOCAL) if (get_addr_family () == AF_LOCAL)
@ -1487,10 +1489,15 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
for (DWORD i = 0; i < wsamsg->dwBufferCount; for (DWORD i = 0; i < wsamsg->dwBufferCount;
off >= wsamsg->lpBuffers[i].len && (++i, off = 0)) off >= wsamsg->lpBuffers[i].len && (++i, off = 0))
{ {
buf.buf = wsamsg->lpBuffers[i].buf + off; /* FIXME? Use the same technique in call to WSASendMsg? */
buf.len = wsamsg->lpBuffers[i].len - off; if (!use_sendmsg)
if (buf.len > 65520) /* See net.cc:fdsock() and MSDN KB 823764 */ {
buf.len = 65520; buf.buf = wsamsg->lpBuffers[i].buf + off;
buf.len = wsamsg->lpBuffers[i].len - off;
/* See net.cc:fdsock() and MSDN KB 823764 */
if (buf.len >= (unsigned) wmem ())
buf.len = (unsigned) wmem () - 1;
}
do do
{ {
@ -1513,6 +1520,8 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
{ {
off += ret; off += ret;
sum += ret; sum += ret;
if (use_sendmsg)
break;
} }
else if (is_nonblocking () || err != WSAEWOULDBLOCK) else if (is_nonblocking () || err != WSAEWOULDBLOCK)
break; 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). /* 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 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 connected to a remote machine, then calling WSADuplicateSocket on
fails with WinSock error 10022, WSAEINVAL. An explanation for this fork/exec fails with WinSock error 10022, WSAEINVAL. Fortunately
weird behaviour would be nice. 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? */ (*) Maximum normal TCP window size. Coincidence? */
int rmem = 65520; ((fhandler_socket *) fd)->rmem () = 65536;
int wmem = 65520; ((fhandler_socket *) fd)->wmem () = 65536;
if (::setsockopt (soc, SOL_SOCKET, SO_RCVBUF, (char *) &rmem, sizeof (int))) if (::setsockopt (soc, SOL_SOCKET, SO_RCVBUF,
(char *) &((fhandler_socket *) fd)->rmem (), sizeof (int)))
debug_printf ("setsockopt(SO_RCVBUF) failed, %lu", WSAGetLastError ()); 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 ()); debug_printf ("setsockopt(SO_SNDBUF) failed, %lu", WSAGetLastError ());
return true; 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) const struct sockaddr *to, socklen_t tolen)
{ {
int res; int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd); 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) struct sockaddr *from, socklen_t *fromlen)
{ {
int res; int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd); fhandler_socket *fh = get (fd);
@ -683,8 +688,21 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
else else
set_winsock_errno (); set_winsock_errno ();
} }
else if (level == SOL_SOCKET && optname == SO_REUSEADDR) else if (level == SOL_SOCKET)
fh->saw_reuseaddr (*(int *) optval); 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)", 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) cygwin_recvmsg (int fd, struct msghdr *msg, int flags)
{ {
int res; int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd); fhandler_socket *fh = get (fd);
@ -2924,7 +2941,6 @@ extern "C" int
cygwin_sendmsg (int fd, const struct msghdr *msg, int flags) cygwin_sendmsg (int fd, const struct msghdr *msg, int flags)
{ {
int res; int res;
sig_dispatch_pending ();
fhandler_socket *fh = get (fd); fhandler_socket *fh = get (fd);