Module: wine Branch: master Commit: be9a032693a138795fb57c2f67c0a38b64cf0410 URL: http://source.winehq.org/git/wine.git/?a=commit;h=be9a032693a138795fb57c2f67...
Author: Francois Gouget fgouget@codeweavers.com Date: Wed Jul 13 00:09:18 2011 +0200
ole32: Modify local_server_thread() to recreate the pipe for each request.
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; }