Alexander Morozov : ole32: Avoid a deadlock when a being loaded DLL calls CoRegisterClassObject from its DLL_PROCESS_ATTACH handler .
Module: wine Branch: master Commit: 5857895684020e513f6f3858938fc5ab7a227676 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5857895684020e513f6f385893... Author: Alexander Morozov <amorozov(a)etersoft.ru> Date: Tue Aug 2 15:52:48 2011 +0400 ole32: Avoid a deadlock when a being loaded DLL calls CoRegisterClassObject from its DLL_PROCESS_ATTACH handler. --- dlls/ole32/rpc.c | 45 ++++++++++++++++++--------------------------- 1 files changed, 18 insertions(+), 27 deletions(-) diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 5c981bb..5070117 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -1877,7 +1877,7 @@ struct local_server_params { CLSID clsid; IStream *stream; - HANDLE ready_event; + HANDLE pipe; HANDLE stop_event; HANDLE thread; BOOL multi_use; @@ -1898,7 +1898,7 @@ static DWORD WINAPI local_server_thread(LPVOID param) ULONG res; BOOL multi_use = lsp->multi_use; OVERLAPPED ovl; - HANDLE pipe_event, hPipe, new_pipe; + HANDLE pipe_event, hPipe = lsp->pipe, new_pipe; DWORD bytes; TRACE("Starting threader for %s.\n",debugstr_guid(&lsp->clsid)); @@ -1907,18 +1907,6 @@ 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); - while (1) { if (!ConnectNamedPipe(hPipe, &ovl)) { @@ -2008,8 +1996,9 @@ static DWORD WINAPI local_server_thread(LPVOID param) /* starts listening for a local server */ HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration) { - DWORD tid; + DWORD tid, err; struct local_server_params *lsp; + WCHAR pipefn[100]; lsp = HeapAlloc(GetProcessHeap(), 0, sizeof(*lsp)); if (!lsp) @@ -2018,34 +2007,36 @@ HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, vo lsp->clsid = *clsid; lsp->stream = stream; IStream_AddRef(stream); - lsp->ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!lsp->ready_event) - { - HeapFree(GetProcessHeap(), 0, lsp); - return HRESULT_FROM_WIN32(GetLastError()); - } lsp->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); if (!lsp->stop_event) { - CloseHandle(lsp->ready_event); HeapFree(GetProcessHeap(), 0, lsp); return HRESULT_FROM_WIN32(GetLastError()); } lsp->multi_use = multi_use; + get_localserver_pipe_name(pipefn, &lsp->clsid); + lsp->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); + if (lsp->pipe == INVALID_HANDLE_VALUE) + { + err = GetLastError(); + FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError()); + CloseHandle(lsp->stop_event); + HeapFree(GetProcessHeap(), 0, lsp); + return HRESULT_FROM_WIN32(err); + } + lsp->thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid); if (!lsp->thread) { - CloseHandle(lsp->ready_event); + CloseHandle(lsp->pipe); CloseHandle(lsp->stop_event); HeapFree(GetProcessHeap(), 0, lsp); return HRESULT_FROM_WIN32(GetLastError()); } - WaitForSingleObject(lsp->ready_event, INFINITE); - CloseHandle(lsp->ready_event); - lsp->ready_event = NULL; - *registration = lsp; return S_OK; }
participants (1)
-
Alexandre Julliard