* 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:
parent
01d9574ddd
commit
e665b0aab2
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue