ole32: Use asynchronous I/O for the named pipe server for local servers.
This commit is contained in:
parent
da04018608
commit
24723913e0
@ -1712,7 +1712,7 @@ HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
|||||||
|
|
||||||
while (tries++ < MAXTRIES) {
|
while (tries++ < MAXTRIES) {
|
||||||
TRACE("waiting for %s\n", debugstr_w(pipefn));
|
TRACE("waiting for %s\n", debugstr_w(pipefn));
|
||||||
|
|
||||||
WaitNamedPipeW( pipefn, NMPWAIT_WAIT_FOREVER );
|
WaitNamedPipeW( pipefn, NMPWAIT_WAIT_FOREVER );
|
||||||
hPipe = CreateFileW(pipefn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
|
hPipe = CreateFileW(pipefn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||||
@ -1761,8 +1761,9 @@ struct local_server_params
|
|||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
IStream *stream;
|
IStream *stream;
|
||||||
HANDLE ready_event;
|
HANDLE ready_event;
|
||||||
|
HANDLE stop_event;
|
||||||
|
HANDLE thread;
|
||||||
BOOL multi_use;
|
BOOL multi_use;
|
||||||
HANDLE pipe;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: should call to rpcss instead */
|
/* FIXME: should call to rpcss instead */
|
||||||
@ -1780,40 +1781,44 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||||||
ULARGE_INTEGER newpos;
|
ULARGE_INTEGER newpos;
|
||||||
ULONG res;
|
ULONG res;
|
||||||
BOOL multi_use = lsp->multi_use;
|
BOOL multi_use = lsp->multi_use;
|
||||||
|
OVERLAPPED ovl;
|
||||||
|
HANDLE pipe_event;
|
||||||
|
|
||||||
TRACE("Starting threader for %s.\n",debugstr_guid(&lsp->clsid));
|
TRACE("Starting threader for %s.\n",debugstr_guid(&lsp->clsid));
|
||||||
|
|
||||||
|
memset(&ovl, 0, sizeof(ovl));
|
||||||
get_localserver_pipe_name(pipefn, &lsp->clsid);
|
get_localserver_pipe_name(pipefn, &lsp->clsid);
|
||||||
|
|
||||||
hPipe = CreateNamedPipeW( pipefn, PIPE_ACCESS_DUPLEX,
|
hPipe = CreateNamedPipeW( pipefn, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||||
PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
|
PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
|
||||||
4096, 4096, 500 /* 0.5 second timeout */, NULL );
|
4096, 4096, 500 /* 0.5 second timeout */, NULL );
|
||||||
|
|
||||||
lsp->pipe = hPipe;
|
|
||||||
SetEvent(lsp->ready_event);
|
SetEvent(lsp->ready_event);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, lsp);
|
|
||||||
|
|
||||||
if (hPipe == INVALID_HANDLE_VALUE)
|
if (hPipe == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError());
|
FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ovl.hEvent = pipe_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!ConnectNamedPipe(hPipe,NULL))
|
if (!ConnectNamedPipe(hPipe, &ovl))
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
/* client already connected isn't an error */
|
if (error == ERROR_IO_PENDING)
|
||||||
if (error != ERROR_PIPE_CONNECTED)
|
|
||||||
{
|
{
|
||||||
/* if error wasn't caused by RPC_StopLocalServer closing the
|
HANDLE handles[2] = { pipe_event, lsp->stop_event };
|
||||||
* pipe for us */
|
DWORD ret;
|
||||||
if (error != ERROR_INVALID_HANDLE)
|
ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||||
{
|
if (ret != WAIT_OBJECT_0)
|
||||||
ERR("Failure during ConnectNamedPipe %u\n", error);
|
break;
|
||||||
CloseHandle(hPipe);
|
}
|
||||||
}
|
/* client already connected isn't an error */
|
||||||
|
else if (error != ERROR_PIPE_CONNECTED)
|
||||||
|
{
|
||||||
|
ERR("ConnectNamedPipe failed with error %d\n", GetLastError());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1828,6 +1833,8 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||||||
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
|
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
|
||||||
if (hres) {
|
if (hres) {
|
||||||
FIXME("IStream_Seek failed, %x\n",hres);
|
FIXME("IStream_Seek failed, %x\n",hres);
|
||||||
|
CloseHandle(hPipe);
|
||||||
|
CloseHandle(pipe_event);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1837,11 +1844,14 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||||||
hres = IStream_Read(pStm,buffer,buflen,&res);
|
hres = IStream_Read(pStm,buffer,buflen,&res);
|
||||||
if (hres) {
|
if (hres) {
|
||||||
FIXME("Stream Read failed, %x\n",hres);
|
FIXME("Stream Read failed, %x\n",hres);
|
||||||
|
CloseHandle(hPipe);
|
||||||
|
CloseHandle(pipe_event);
|
||||||
HeapFree(GetProcessHeap(),0,buffer);
|
HeapFree(GetProcessHeap(),0,buffer);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteFile(hPipe,buffer,buflen,&res,NULL);
|
WriteFile(hPipe,buffer,buflen,&res,&ovl);
|
||||||
|
GetOverlappedResult(hPipe, &ovl, NULL, TRUE);
|
||||||
HeapFree(GetProcessHeap(),0,buffer);
|
HeapFree(GetProcessHeap(),0,buffer);
|
||||||
|
|
||||||
FlushFileBuffers(hPipe);
|
FlushFileBuffers(hPipe);
|
||||||
@ -1852,11 +1862,11 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||||||
if (!multi_use)
|
if (!multi_use)
|
||||||
{
|
{
|
||||||
TRACE("single use object, shutting down pipe %s\n", debugstr_w(pipefn));
|
TRACE("single use object, shutting down pipe %s\n", debugstr_w(pipefn));
|
||||||
CloseHandle(hPipe);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IStream_Release(pStm);
|
CloseHandle(hPipe);
|
||||||
|
CloseHandle(pipe_event);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1864,30 +1874,59 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||||||
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration)
|
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration)
|
||||||
{
|
{
|
||||||
DWORD tid;
|
DWORD tid;
|
||||||
HANDLE thread, ready_event;
|
struct local_server_params *lsp;
|
||||||
struct local_server_params *lsp = HeapAlloc(GetProcessHeap(), 0, sizeof(*lsp));
|
|
||||||
|
lsp = HeapAlloc(GetProcessHeap(), 0, sizeof(*lsp));
|
||||||
|
if (!lsp)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
lsp->clsid = *clsid;
|
lsp->clsid = *clsid;
|
||||||
lsp->stream = stream;
|
lsp->stream = stream;
|
||||||
IStream_AddRef(stream);
|
IStream_AddRef(stream);
|
||||||
lsp->ready_event = ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
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;
|
lsp->multi_use = multi_use;
|
||||||
|
|
||||||
thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid);
|
lsp->thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid);
|
||||||
if (!thread)
|
if (!lsp->thread)
|
||||||
|
{
|
||||||
|
CloseHandle(lsp->ready_event);
|
||||||
|
CloseHandle(lsp->stop_event);
|
||||||
|
HeapFree(GetProcessHeap(), 0, lsp);
|
||||||
return HRESULT_FROM_WIN32(GetLastError());
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
CloseHandle(thread);
|
}
|
||||||
|
|
||||||
WaitForSingleObject(ready_event, INFINITE);
|
WaitForSingleObject(lsp->ready_event, INFINITE);
|
||||||
CloseHandle(ready_event);
|
CloseHandle(lsp->ready_event);
|
||||||
|
lsp->ready_event = NULL;
|
||||||
|
|
||||||
*registration = lsp->pipe;
|
*registration = lsp;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stops listening for a local server */
|
/* stops listening for a local server */
|
||||||
void RPC_StopLocalServer(void *registration)
|
void RPC_StopLocalServer(void *registration)
|
||||||
{
|
{
|
||||||
HANDLE pipe = registration;
|
struct local_server_params *lsp = registration;
|
||||||
CloseHandle(pipe);
|
|
||||||
|
/* signal local_server_thread to stop */
|
||||||
|
SetEvent(lsp->stop_event);
|
||||||
|
/* wait for it to exit */
|
||||||
|
WaitForSingleObject(lsp->thread, INFINITE);
|
||||||
|
|
||||||
|
IStream_Release(lsp->stream);
|
||||||
|
CloseHandle(lsp->stop_event);
|
||||||
|
CloseHandle(lsp->thread);
|
||||||
|
HeapFree(GetProcessHeap(), 0, lsp);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user