* fhandler.h (fhandler_socket::recv_internal): Add bool parameter.

Add regparm attribute.
	* fhandler_socket.cc (fhandler_socket::read): Call recv_internal with
	second parameter set to false.
	(fhandler_socket::readv): Ditto.
	(fhandler_socket::recvfrom): Ditto.
	(fhandler_socket::recv_internal): Convert use_recvmsg from local
	variable to parameter.  Use as request for using WSARecvMsg.  Only
	fail if WSARecvMsg can't be loaded and wsamsg->Control.len > 0,
	otherwise use WSARecv{From}.  Restrict dwFlags to MSG_PEEK when using
	WSARecvMsg.
	(fhandler_socket::recvmsg): Prefer using WSARecvMsg.  Change priority
	of tests for not using WSARecvMsg.  Call recv_internal with second
	parameter set accordingly.
This commit is contained in:
Corinna Vinschen 2012-08-01 09:00:53 +00:00
parent 01d9574ddd
commit e665b0aab2
3 changed files with 36 additions and 15 deletions

View File

@ -1,3 +1,20 @@
2012-08-01 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (fhandler_socket::recv_internal): Add bool parameter.
Add regparm attribute.
* fhandler_socket.cc (fhandler_socket::read): Call recv_internal with
second parameter set to false.
(fhandler_socket::readv): Ditto.
(fhandler_socket::recvfrom): Ditto.
(fhandler_socket::recv_internal): Convert use_recvmsg from local
variable to parameter. Use as request for using WSARecvMsg. Only
fail if WSARecvMsg can't be loaded and wsamsg->Control.len > 0,
otherwise use WSARecv{From}. Restrict dwFlags to MSG_PEEK when using
WSARecvMsg.
(fhandler_socket::recvmsg): Prefer using WSARecvMsg. Change priority
of tests for not using WSARecvMsg. Call recv_internal with second
parameter set accordingly.
2012-08-01 Corinna Vinschen <corinna@vinschen.de> 2012-08-01 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in: Semi-revert patch from 2012-07-01, assuming the previous * Makefile.in: Semi-revert patch from 2012-07-01, assuming the previous

View File

@ -558,7 +558,7 @@ class fhandler_socket: public fhandler_base
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1); ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
inline ssize_t recv_internal (struct _WSAMSG *wsamsg); inline ssize_t recv_internal (struct _WSAMSG *wsamsg, bool use_recvmsg) __attribute__ ((regparm (3)));
ssize_t recvfrom (void *ptr, size_t len, int flags, ssize_t recvfrom (void *ptr, size_t len, int flags,
struct sockaddr *from, int *fromlen); struct sockaddr *from, int *fromlen);
ssize_t recvmsg (struct msghdr *msg, int flags); ssize_t recvmsg (struct msghdr *msg, int flags);

View File

@ -1330,7 +1330,7 @@ fhandler_socket::read (void *in_ptr, size_t& len)
{ {
WSABUF wsabuf = { len, (char *) in_ptr }; WSABUF wsabuf = { len, (char *) in_ptr };
WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 }; WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
len = recv_internal (&wsamsg); len = recv_internal (&wsamsg, false);
} }
int int
@ -1346,7 +1346,7 @@ fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
wsaptr->buf = (char *) iovptr->iov_base; wsaptr->buf = (char *) iovptr->iov_base;
} }
WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0, NULL}, 0 }; WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0, NULL}, 0 };
return recv_internal (&wsamsg); return recv_internal (&wsamsg, false);
} }
extern "C" { extern "C" {
@ -1375,28 +1375,32 @@ get_ext_funcptr (SOCKET sock, void *funcptr)
} }
inline ssize_t inline ssize_t
fhandler_socket::recv_internal (LPWSAMSG wsamsg) fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
{ {
ssize_t res = 0; ssize_t res = 0;
DWORD ret = 0, wret; DWORD ret = 0, wret;
int evt_mask = FD_READ | ((wsamsg->dwFlags & MSG_OOB) ? FD_OOB : 0); int evt_mask = FD_READ | ((wsamsg->dwFlags & MSG_OOB) ? FD_OOB : 0);
LPWSABUF &wsabuf = wsamsg->lpBuffers; LPWSABUF &wsabuf = wsamsg->lpBuffers;
ULONG &wsacnt = wsamsg->dwBufferCount; ULONG &wsacnt = wsamsg->dwBufferCount;
bool use_recvmsg = false;
static NO_COPY LPFN_WSARECVMSG WSARecvMsg; static NO_COPY LPFN_WSARECVMSG WSARecvMsg;
DWORD wait_flags = wsamsg->dwFlags; DWORD wait_flags = wsamsg->dwFlags;
bool waitall = !!(wait_flags & MSG_WAITALL); bool waitall = !!(wait_flags & MSG_WAITALL);
wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE); wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
if (wsamsg->Control.len > 0) if (use_recvmsg)
{ {
if (!WSARecvMsg if (!WSARecvMsg
&& get_ext_funcptr (get_socket (), &WSARecvMsg) == SOCKET_ERROR) && get_ext_funcptr (get_socket (), &WSARecvMsg) == SOCKET_ERROR)
{
if (wsamsg->Control.len > 0)
{ {
set_winsock_errno (); set_winsock_errno ();
return SOCKET_ERROR; return SOCKET_ERROR;
} }
use_recvmsg = true; use_recvmsg = false;
}
else /* Only MSG_PEEK is supported by WSARecvMsg. */
wsamsg->dwFlags &= MSG_PEEK;
} }
if (waitall) if (waitall)
{ {
@ -1503,7 +1507,7 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
&wsabuf, 1, &wsabuf, 1,
{ 0, NULL}, { 0, NULL},
flags }; flags };
ssize_t ret = recv_internal (&wsamsg); ssize_t ret = recv_internal (&wsamsg, false);
if (fromlen) if (fromlen)
*fromlen = wsamsg.namelen; *fromlen = wsamsg.namelen;
return ret; return ret;
@ -1518,12 +1522,12 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
/* Disappointing but true: Even if WSARecvMsg is supported, it's only /* Disappointing but true: Even if WSARecvMsg is supported, it's only
supported for datagram and raw sockets. */ supported for datagram and raw sockets. */
if (!wincap.has_recvmsg () || get_socket_type () == SOCK_STREAM bool use_recvmsg = true;
|| get_addr_family () == AF_LOCAL) if (get_socket_type () == SOCK_STREAM || get_addr_family () == AF_LOCAL
|| !wincap.has_recvmsg ())
{ {
use_recvmsg = false;
msg->msg_controllen = 0; msg->msg_controllen = 0;
if (!CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
msg->msg_flags = 0;
} }
WSABUF wsabuf[msg->msg_iovlen]; WSABUF wsabuf[msg->msg_iovlen];
@ -1538,7 +1542,7 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
wsabuf, msg->msg_iovlen, wsabuf, msg->msg_iovlen,
{ msg->msg_controllen, (char *) msg->msg_control }, { msg->msg_controllen, (char *) msg->msg_control },
flags }; flags };
ssize_t ret = recv_internal (&wsamsg); ssize_t ret = recv_internal (&wsamsg, use_recvmsg);
if (ret >= 0) if (ret >= 0)
{ {
msg->msg_namelen = wsamsg.namelen; msg->msg_namelen = wsamsg.namelen;