* fhandler.h (fhandler_socket::wait_for_events): Take additional

parameter "dontwait".
	* fhandler_socket.cc (fhandler_socket::wait_for_events): Act as if the
	socket is non-blocking if dontwait is true.
	(fhandler_socket::recv_internal): Use incoming MSG_DONTWAIT flag to
	set the wait_for_events dontwait parameter.
	(fhandler_socket::send_internal): Ditto.  Optimize code slightly.
	* include/cygwin/socket.h (MSG_DONTWAIT): Define.
	* include/cygwin/version.h: Bump API minor number.
This commit is contained in:
Corinna Vinschen 2009-03-09 14:40:45 +00:00
parent c47426aedb
commit 71d13bca55
5 changed files with 30 additions and 16 deletions

View File

@ -1,3 +1,15 @@
2009-03-09 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (fhandler_socket::wait_for_events): Take additional
parameter "dontwait".
* fhandler_socket.cc (fhandler_socket::wait_for_events): Act as if the
socket is non-blocking if dontwait is true.
(fhandler_socket::recv_internal): Use incoming MSG_DONTWAIT flag to
set the wait_for_events dontwait parameter.
(fhandler_socket::send_internal): Ditto. Optimize code slightly.
* include/cygwin/socket.h (MSG_DONTWAIT): Define.
* include/cygwin/version.h: Bump API minor number.
2009-03-09 Corinna Vinschen <corinna@vinschen.de> 2009-03-09 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Export wcsftime. * cygwin.din: Export wcsftime.

View File

@ -420,7 +420,7 @@ class fhandler_socket: public fhandler_base
const HANDLE wsock_event () const { return wsock_evt; } const HANDLE wsock_event () const { return wsock_evt; }
const LONG serial_number () const { return wsock_events->serial_number; } const LONG serial_number () const { return wsock_events->serial_number; }
private: private:
int wait_for_events (const long event_mask); int wait_for_events (const long event_mask, bool dontwait = false);
void release_events (); void release_events ();
pid_t sec_pid; pid_t sec_pid;

View File

@ -580,7 +580,7 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
} }
int int
fhandler_socket::wait_for_events (const long event_mask) fhandler_socket::wait_for_events (const long event_mask, bool dontwait)
{ {
if (async_io ()) if (async_io ())
return 0; return 0;
@ -590,7 +590,7 @@ fhandler_socket::wait_for_events (const long event_mask)
while (!(ret = evaluate_events (event_mask, events, true)) && !events) while (!(ret = evaluate_events (event_mask, events, true)) && !events)
{ {
if (is_nonblocking ()) if (is_nonblocking () || dontwait)
{ {
WSASetLastError (WSAEWOULDBLOCK); WSASetLastError (WSAEWOULDBLOCK);
return SOCKET_ERROR; return SOCKET_ERROR;
@ -1312,7 +1312,8 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg)
bool use_recvmsg = false; bool use_recvmsg = false;
static LPFN_WSARECVMSG WSARecvMsg; static LPFN_WSARECVMSG WSARecvMsg;
bool waitall = (wsamsg->dwFlags & MSG_WAITALL); bool waitall = !!(wsamsg->dwFlags & MSG_WAITALL);
bool dontwait = !!(wsamsg->dwFlags & MSG_DONTWAIT);
wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE); wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
if (wsamsg->Control.len > 0) if (wsamsg->Control.len > 0)
{ {
@ -1339,7 +1340,7 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg)
/* Note: Don't call WSARecvFrom(MSG_PEEK) without actually having data /* Note: Don't call WSARecvFrom(MSG_PEEK) without actually having data
waiting in the buffers, otherwise the event handling gets messed up waiting in the buffers, otherwise the event handling gets messed up
for some reason. */ for some reason. */
while (!(res = wait_for_events (evt_mask | FD_CLOSE)) while (!(res = wait_for_events (evt_mask | FD_CLOSE, dontwait))
|| saw_shutdown_read ()) || saw_shutdown_read ())
{ {
if (use_recvmsg) if (use_recvmsg)
@ -1472,7 +1473,10 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
DWORD ret = 0, err = 0, sum = 0, off = 0; DWORD ret = 0, err = 0, sum = 0, off = 0;
WSABUF buf; WSABUF buf;
bool use_sendmsg = false; bool use_sendmsg = false;
bool dontwait = !!(flags & MSG_DONTWAIT);
bool nosignal = !(flags & MSG_NOSIGNAL);
flags &= (MSG_OOB | MSG_DONTROUTE);
if (wsamsg->Control.len > 0) if (wsamsg->Control.len > 0)
use_sendmsg = true; use_sendmsg = true;
for (DWORD i = 0; i < wsamsg->dwBufferCount; for (DWORD i = 0; i < wsamsg->dwBufferCount;
@ -1486,14 +1490,10 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
do do
{ {
if (use_sendmsg) if (use_sendmsg)
res = WSASendMsg (get_socket (), wsamsg, res = WSASendMsg (get_socket (), wsamsg, flags, &ret, NULL, NULL);
flags & (MSG_OOB | MSG_DONTROUTE), &ret,
NULL, NULL);
else else
res = WSASendTo (get_socket (), &buf, 1, &ret, res = WSASendTo (get_socket (), &buf, 1, &ret, flags,
flags & (MSG_OOB | MSG_DONTROUTE), wsamsg->name, wsamsg->namelen, NULL, NULL);
wsamsg->name, wsamsg->namelen,
NULL, NULL);
if (res && (err = WSAGetLastError ()) == WSAEWOULDBLOCK) if (res && (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
{ {
LOCK_EVENTS; LOCK_EVENTS;
@ -1502,7 +1502,7 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
} }
} }
while (res && err == WSAEWOULDBLOCK while (res && err == WSAEWOULDBLOCK
&& !(res = wait_for_events (FD_WRITE | FD_CLOSE))); && !(res = wait_for_events (FD_WRITE | FD_CLOSE), dontwait));
if (!res) if (!res)
{ {
@ -1527,7 +1527,7 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM) if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM)
{ {
set_errno (EPIPE); set_errno (EPIPE);
if (!(flags & MSG_NOSIGNAL)) if (!nosignal)
raise (SIGPIPE); raise (SIGPIPE);
} }
} }

View File

@ -1,6 +1,6 @@
/* cygwin/socket.h /* cygwin/socket.h
Copyright 1999, 2000, 2001, 2005, 2006, 2007 Red Hat, Inc. Copyright 1999, 2000, 2001, 2005, 2006, 2007, 2009 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -191,6 +191,7 @@ struct OLD_msghdr
#define MSG_PEEK 0x2 /* peek at incoming message */ #define MSG_PEEK 0x2 /* peek at incoming message */
#define MSG_DONTROUTE 0x4 /* send without using routing tables */ #define MSG_DONTROUTE 0x4 /* send without using routing tables */
#define MSG_WAITALL 0x8 /* wait for all requested bytes */ #define MSG_WAITALL 0x8 /* wait for all requested bytes */
#define MSG_DONTWAIT 0x10 /* selective non-blocking operation */
#define MSG_NOSIGNAL 0x20 /* Don't raise SIGPIPE */ #define MSG_NOSIGNAL 0x20 /* Don't raise SIGPIPE */
#define MSG_TRUNC 0x0100 /* Normal data truncated */ #define MSG_TRUNC 0x0100 /* Normal data truncated */
#define MSG_CTRUNC 0x0200 /* Control data truncated */ #define MSG_CTRUNC 0x0200 /* Control data truncated */

View File

@ -352,12 +352,13 @@ details. */
201: Export wprintf, fwprintf, swprintf, vwprintf, vfwprintf, vswprintf. 201: Export wprintf, fwprintf, swprintf, vwprintf, vfwprintf, vswprintf.
202: Export gethostbyname2. 202: Export gethostbyname2.
203: Export wcsftime. 203: Export wcsftime.
204: recv/send flag MSG_DONTWAIT added.
*/ */
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 203 #define CYGWIN_VERSION_API_MINOR 204
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible