PLEASE TEST: New implementation of blocking socket I/O

Pierre A. Humblet Pierre.Humblet@ieee.org
Fri Apr 2 05:31:00 GMT 2004


At 10:04 AM 4/1/2004 -0500, Pierre A. Humblet wrote:
>Corinna Vinschen wrote:
>
>> I've also applied the following:  If the FD_CLOSE event is recognized,
>> then ret is set to 0 only if wsa_err is still 0.  Otherwise it would
>> have been possible that even in case an error has happened, the function
>> returns 0.
>
>Will try again tonight.
> 
>> > No luck, wsock errno is still 0, but sendmsg surely fails.

Still ditto

  156 2626629 [main] cvs 866951 writev: writev (3, 0x7DE810, 1)
  245 2626874 [main] cvs 866951 __set_errno: void __set_winsock_errno(const
char*, int):374 val 0
  172 2627046 [main] cvs 866951 __set_winsock_errno: sendmsg:1102 - winsock
error 0 -> errno 0
  149 2627195 [main] cvs 866951 writev: -1 = write (3, 0x7DE810, 1), errno 0
  270 2627465 [main] cvs 866951 sig_dispatch_pending: exit_state 0, cur
thread id 0xFFF2C2B9, sigtid 0xFFF6B7A5, sigq.start.next 0x0

I have determined that the error is from wsock_event::wait and I have
modified the code and put a try_to_debug() in case ret != 0.

DWORD what, why;

wsock_event::wait (int sock, int &closed)
{
  int ret = SOCKET_ERROR;
  int wsa_err = 0;
  WSAEVENT ev[2] = { event, signal_arrived };
  WSANETWORKEVENTS evts;
  memset(&evts, 0, sizeof(evts));
  what = WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE);
  switch (what)
    {
      case WSA_WAIT_EVENT_0:
	why = WSAEnumNetworkEvents (sock, event, &evts);

(gdb) p what
$1 = 0
(gdb) p why
$2 = 0
(gdb) p evts
$3 = {lNetworkEvents = 0, iErrorCode = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
(gdb) p /x sock
$4 = 0x102
(gdb) p /x event
$5 = 0x154

Weird. 
Sysinternals doesn't show a handle 0x102, FWIW.

>> 
>> > And yes, from time to time it does like in my first report, hanging
>> >   158 2552618 [main] cvs 540017 readv: readv (4, 0x7DEBC0, 1) blocking,
>> > sigcatchers 6
>> >   154 2552772 [main] cvs 540017 readv: no need to call ready_for_read
>> 
>> Hmm 2.  That really stumps me.  Is it possible that WSARecvFrom receives
>> partial data, sets ret to a value > 0 and nevertheless returns
WSAEWOULDBLOCK?
>
>What happens if there is already data in the buffer when the event
>is created? Will it be set then, or when more data arrives (if ever ?).
>In other words isn't it better to try reading before waiting?

This has not happened again in 25 trials.
However on rereading MSDN, your original code should be fine:
"If a network event has already happened when the application calls
WSAEventSelect or when the reenabling function is called, then a network 
event is recorded and the associated event object is set as appropriate."

Pierre




More information about the Cygwin-developers mailing list