From 9f426df0a8d6f86c9779e3f9af57fa01e4fa8173 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Wed, 5 Jan 2005 17:30:04 +0000 Subject: [PATCH] - Fix race on apartment creation. - Display errors in decimal to make searching for the meaning in winerror.h easier. --- dlls/ole32/rpc.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 82b4ae9e6a2..e469ae7fe59 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -125,7 +125,7 @@ static HRESULT WINAPI read_pipe(HANDLE hf, LPVOID ptr, DWORD size) { DWORD res; if (!ReadFile(hf,ptr,size,&res,NULL)) { - FIXME("Failed to read from %p, le is %lx\n",hf,GetLastError()); + FIXME("Failed to read from %p, le is %ld\n",hf,GetLastError()); return E_FAIL; } if (res!=size) { @@ -165,7 +165,7 @@ static HRESULT WINAPI write_pipe(HANDLE hf, LPVOID ptr, DWORD size) { DWORD res; if (!WriteFile(hf,ptr,size,&res,NULL)) { - FIXME("Failed to write to %p, le is %lx\n",hf,GetLastError()); + FIXME("Failed to write to %p, le is %ld\n",hf,GetLastError()); return E_FAIL; } if (res!=size) { @@ -877,6 +877,12 @@ static DWORD WINAPI stub_dispatch_thread(LPVOID param) return 0; } +struct apartment_listener_params +{ + APARTMENT *apt; + HANDLE event; +}; + /* This thread listens on a named pipe for each apartment that exports * objects. It deals with incoming connection requests. Each time a * client connects a separate thread is spawned for that particular @@ -884,11 +890,15 @@ static DWORD WINAPI stub_dispatch_thread(LPVOID param) * * This architecture is different in native DCOM. */ -static DWORD WINAPI apartment_listener_thread(LPVOID param) +static DWORD WINAPI apartment_listener_thread(LPVOID p) { char pipefn[200]; HANDLE listenPipe; - APARTMENT *apt = (APARTMENT *) param; + struct apartment_listener_params * params = (struct apartment_listener_params *)p; + APARTMENT *apt = params->apt; + HANDLE event = params->event; + + HeapFree(GetProcessHeap(), 0, params); /* we must join the marshalling threads apartment. we already have a ref here */ NtCurrentTeb()->ReservedForOle = apt; @@ -907,15 +917,25 @@ static DWORD WINAPI apartment_listener_thread(LPVOID param) NMPWAIT_USE_DEFAULT_WAIT, NULL ); + + /* tell function that started this thread that we have attempted to created the + * named pipe. */ + if (event) { + SetEvent(event); + event = NULL; + } + if (listenPipe == INVALID_HANDLE_VALUE) { - FIXME("pipe creation failed for %s, error %lx\n",pipefn,GetLastError()); + FIXME("pipe creation failed for %s, error %ld\n",pipefn,GetLastError()); return 1; /* permanent failure, so quit stubmgr thread */ } + if (!ConnectNamedPipe(listenPipe,NULL)) { - ERR("Failure during ConnectNamedPipe %lx!\n",GetLastError()); + ERR("Failure during ConnectNamedPipe %ld!\n",GetLastError()); CloseHandle(listenPipe); continue; } + PIPE_StartRequestThread(listenPipe); } return 0; @@ -939,7 +959,18 @@ void start_apartment_listener_thread() if (!apt->listenertid) { - CreateThread(NULL, 0, apartment_listener_thread, apt, 0, &apt->listenertid); + HANDLE thread; + HANDLE event = CreateEventW(NULL, TRUE, FALSE, NULL); + struct apartment_listener_params * params = HeapAlloc(GetProcessHeap(), 0, sizeof(*params)); + + params->apt = apt; + params->event = event; + thread = CreateThread(NULL, 0, apartment_listener_thread, params, 0, &apt->listenertid); + CloseHandle(thread); + /* wait for pipe to be created before returning, otherwise we + * might try to use it and fail */ + WaitForSingleObject(event, INFINITE); + CloseHandle(event); } }