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