On Tue, 14 Mar 2000, Ove Kaaven wrote:

>... 
> application receives notifications, notices FD_READ, and calls recv() to
> read some of the data. recv() reads out the data and sends a reenable
> request to wineserver to trigger further FD_READ notifications
> 
> wineserver socket handler receives reenable request and attempts to
> reenable POLLIN. However, polling has been completely disabled and cannot
> be reenabled using set_select_events(). As a consequence, no further
> notifications will be sent.
> 
> application never gets to read any remaining data
> 

  How about this

  a) Don't set FD_CLOSE in sock->pmask on POLLHUP for normal data flow
     if recv( ..., MSG_PEEK) returns > 0. Disable polling for this socket. 

  b) In the reenabler for FD_READ event, if WS_FD_CONNECTED is missing, 
     FD_CLOSE is not present in sock->pmask and recv( ..., MSG_PEEK)
     returns zero or less then set sock->pmask to FD_CLOSE and do
     set_event(sock->event) to deliver it.

Alex  

--- sock.c      Fri Dec 31 19:56:28 1999
+++ sock.new.c  Wed Mar 15 00:42:51 2000
@@ -168,17 +168,23 @@
         }
         if (event & (POLLERR|POLLHUP))
         {
+           unsigned n;
             sock->errors[FD_CLOSE_BIT] = sock_error( sock->obj.fd );
             /* we got an error, socket closing? */
             sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
-            sock->pmask |= FD_CLOSE;
+            if( recv( sock->obj.fd, &n, 1, MSG_PEEK ) <= 0 )
+                sock->pmask |= FD_CLOSE;
             if (debug_level)
                 fprintf(stderr, "socket %d aborted by error %d\n",
                         sock->obj.fd, sock->errors[FD_CLOSE_BIT]);
         }
     }

-    sock_reselect( sock );
+    if( event & (POLLERR|POLLHUP) )
+        set_select_events( &sock->obj, -1 );
+    else
+        sock_reselect( sock );
+
     /* wake up anyone waiting for whatever just happened */
     emask = sock->pmask & sock->mask;
     if (debug_level && emask)
@@ -498,10 +504,22 @@
     sock=(struct
sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
     if (!sock)
        return;
+
     sock->pmask &= ~req->mask; /* is this safe? */
     sock->hmask &= ~req->mask;
     sock->state |= req->sstate;
     sock->state &= ~req->cstate;
-    sock_reselect( sock );
+
+    if( (req->mask & FD_READ) && !(sock->state & WS_FD_CONNECTED) )
+    {
+       unsigned n;
+       if( recv( sock->obj.fd, &n, 1, MSG_PEEK) <= 0 )
+           sock->pmask |= sock->mask & FD_CLOSE;
+       else
+           sock->pmask |= sock->mask & FD_READ;
+       set_event( sock->event );
+    }
+    else
+       sock_reselect( sock );
     release_object( &sock->obj );
 } 

Reply via email to