Module: wine Branch: master Commit: f01c1c429d9bb35e4831efc217bfd236f5a023b2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f01c1c429d9bb35e4831efc217...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Aug 1 16:20:40 2011 +0200
ole32: Fix a couple of race conditions with the local server pipe.
---
dlls/ole32/rpc.c | 44 ++++++++++++++++++++++++-------------------- 1 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 1a0b575..8ac5d2d 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -1890,7 +1890,7 @@ static DWORD WINAPI local_server_thread(LPVOID param) ULONG res; BOOL multi_use = lsp->multi_use; OVERLAPPED ovl; - HANDLE pipe_event; + HANDLE pipe_event, hPipe, new_pipe; DWORD bytes;
TRACE("Starting threader for %s.\n",debugstr_guid(&lsp->clsid)); @@ -1899,22 +1899,19 @@ static DWORD WINAPI local_server_thread(LPVOID param) get_localserver_pipe_name(pipefn, &lsp->clsid); ovl.hEvent = pipe_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+ 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; + } + SetEvent(lsp->ready_event); - /* 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; - }
+ while (1) { if (!ConnectNamedPipe(hPipe, &ovl)) { DWORD error = GetLastError(); @@ -1976,18 +1973,25 @@ 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");
if (!multi_use) { TRACE("single use object, shutting down pipe %s\n", debugstr_w(pipefn)); + CloseHandle(hPipe); break; } + new_pipe = CreateNamedPipeW( pipefn, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, + 4096, 4096, 500 /* 0.5 second timeout */, NULL ); + CloseHandle(hPipe); + if (new_pipe == INVALID_HANDLE_VALUE) + { + FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError()); + CloseHandle(pipe_event); + return 1; + } + hPipe = new_pipe; } CloseHandle(pipe_event); return 0;