Improved FD_CLOSE scheme for sockets

Martin Wilck Martin.Wilck at fujitsu-siemens.com
Fri Apr 26 14:11:15 CDT 2002


Just a small patch to the server sock.c - it tries to implement exactly
the strategies that I described in my previous FD_CLOSE posting.

Seems to work pretty well with my test cases. It makes a difference
to my previous implementation only in rare cases, but I am sure it will be
better at preventing server busy-loops in these cases.

Martin

diff -ruNX ignore CVS/wine/server/sock.c TMP/wine/server/sock.c
--- CVS/wine/server/sock.c	Fri Apr 26 20:58:26 2002
+++ TMP/wine/server/sock.c	Fri Apr 26 20:36:44 2002
@@ -188,8 +188,6 @@
     /* We need this to delay FD_CLOSE events until all pending overlapped requests are processed */
     if ( !events || async_active ) return;

-    if (events & FD_CLOSE) sock->hmask |= FD_CLOSE;
-
     if (sock->event)
     {
         if (debug_level) fprintf(stderr, "signalling events %x ptr %p\n", events, sock->event );
@@ -284,7 +282,7 @@
             {
                 /* incoming data */
                 sock->pmask |= FD_READ;
-                sock->hmask |= FD_READ;
+                sock->hmask |= (FD_READ|FD_CLOSE);
                 sock->errors[FD_READ_BIT] = 0;
                 if (debug_level)
                     fprintf(stderr, "socket %d is readable\n", sock->obj.fd );
@@ -330,6 +328,7 @@
             if ( event & ( POLLERR|POLLHUP ) )
                  sock->state &= ~(FD_WINE_CONNECTED|FD_WRITE);
             sock->pmask |= FD_CLOSE;
+            sock->hmask |= FD_CLOSE;
             if (debug_level)
                 fprintf(stderr, "socket %d aborted by error %d, event: %x - removing from select loop\n",
                         sock->obj.fd, sock->errors[FD_CLOSE_BIT], event);
@@ -390,7 +389,7 @@
     if (mask & FD_WRITE || (sock->flags & WSA_FLAG_OVERLAPPED && IS_READY (sock->write_q)))
         ev |= POLLOUT;
     /* We use POLLIN with 0 bytes recv() as FD_CLOSE indication. */
-    if (sock->mask & ~sock->hmask & FD_CLOSE && !(sock->hmask & FD_READ) )
+    if (sock->mask & ~sock->hmask & FD_CLOSE)
         ev |= POLLIN;

     return ev;
@@ -447,6 +446,7 @@
     {
     case ASYNC_TYPE_READ:
         q = &sock->read_q;
+        sock->hmask &= ~FD_CLOSE;
         break;
     case ASYNC_TYPE_WRITE:
         q = &sock->write_q;
@@ -478,7 +478,7 @@
                 async_insert ( q, async );
         }
     }
-    else if ( async ) destroy_async ( async );
+    else if ( async ) destroy_async ( async );
     else set_error ( STATUS_INVALID_PARAMETER );

     pollev = sock_reselect ( sock );
@@ -788,6 +788,8 @@

     sock->pmask &= ~req->mask; /* is this safe? */
     sock->hmask &= ~req->mask;
+    if ( req->mask & FD_READ )
+        sock->hmask &= ~FD_CLOSE;
     sock->state |= req->sstate;
     sock->state &= ~req->cstate;








More information about the wine-devel mailing list