ole32: Modify local_server_thread() to recreate the pipe for each request.

Francois Gouget fgouget at codeweavers.com
Tue Jul 12 17:09:18 CDT 2011


This avoids having the named pipe get stuck in the STATUS_PIPE_BUSY state after the DisconnectNamedPipe() call.
---
 dlls/ole32/rpc.c |   38 +++++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c
index 7801d9f..1a0b575 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -1879,7 +1879,6 @@ struct local_server_params
 static DWORD WINAPI local_server_thread(LPVOID param)
 {
     struct local_server_params * lsp = param;
-    HANDLE		hPipe;
     WCHAR 		pipefn[100];
     HRESULT		hres;
     IStream		*pStm = lsp->stream;
@@ -1898,22 +1897,24 @@ static DWORD WINAPI local_server_thread(LPVOID param)
 
     memset(&ovl, 0, sizeof(ovl));
     get_localserver_pipe_name(pipefn, &lsp->clsid);
-
-    hPipe = CreateNamedPipeW( pipefn, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
-                              PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
-                              4096, 4096, 500 /* 0.5 second timeout */, NULL );
+    ovl.hEvent = pipe_event = CreateEventW(NULL, FALSE, FALSE, NULL);
 
     SetEvent(lsp->ready_event);
-
-    if (hPipe == INVALID_HANDLE_VALUE)
-    {
-        FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError());
-        return 1;
-    }
-
-    ovl.hEvent = pipe_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-    
+    /* Clients trying to connect between now and CreateNamedPipeW() will
+     * fail and will have to retry. See also the end of the loop.
+     */
     while (1) {
+        HANDLE hPipe;
+        hPipe = CreateNamedPipeW( pipefn, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+                                  PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
+                                  4096, 4096, 500 /* 0.5 second timeout */, NULL );
+        if (hPipe == INVALID_HANDLE_VALUE)
+        {
+            FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError());
+            CloseHandle(pipe_event);
+            return 1;
+        }
+
         if (!ConnectNamedPipe(hPipe, &ovl))
         {
             DWORD error = GetLastError();
@@ -1923,12 +1924,16 @@ static DWORD WINAPI local_server_thread(LPVOID param)
                 DWORD ret;
                 ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
                 if (ret != WAIT_OBJECT_0)
+                {
+                    CloseHandle(hPipe);
                     break;
+                }
             }
             /* client already connected isn't an error */
             else if (error != ERROR_PIPE_CONNECTED)
             {
                 ERR("ConnectNamedPipe failed with error %d\n", GetLastError());
+                CloseHandle(hPipe);
                 break;
             }
         }
@@ -1971,6 +1976,10 @@ static DWORD WINAPI local_server_thread(LPVOID param)
 
         FlushFileBuffers(hPipe);
         DisconnectNamedPipe(hPipe);
+        CloseHandle(hPipe);
+        /* Clients trying to connect between now and CreateNamedPipeW() will
+         * fail and will have to retry.
+         */
 
         TRACE("done marshalling IClassFactory\n");
 
@@ -1980,7 +1989,6 @@ static DWORD WINAPI local_server_thread(LPVOID param)
             break;
         }
     }
-    CloseHandle(hPipe);
     CloseHandle(pipe_event);
     return 0;
 }
-- 
1.7.5.4



More information about the wine-patches mailing list