Re: CloseHandle() hangs on Named Pipe
- From: Tommy <bad@xxxxxxxxxxxxx>
- Date: Fri, 05 Dec 2008 15:53:38 -0500
PaulH wrote:
On Dec 5, 9:31 am, "Alexander Grigoriev" <al...@xxxxxxxxxxxxx> wrote:All operations on an I/O handle opened in non-overlapped mode are
serialized. That includes CloseHandle.
Then what is the expected method of cleanly closing a multi-threaded
pipe server? This method works fine for a multi-threaded Win32 socket
server.
But that is why you have specific (and well defined) socket API functions vs specific pipe functions where the handling are not 100% the same. Although same virtual device I/O handling is attempted with named pipes, but its been our experience that using named pipes in any critical server application can be extremely sensitive. Looking at some our old asynchronous piping client/server code, we don't even use ConnectNamedPipe(). You could just create the pipe and wait on the ReadFile() asynchronously.
Anyway, try this:
Use a StopServer() "Client connection" to wake up the server and stop it. In other words, in your main thread your "Stop Server" action does this:
- MainThread(): Calls StopServer()
- StopServer(): set a global event signal
- StopServer(): connects (CreateFile/CloseHandle) to the pipe.
- PipeServerThread(): ConnectNamedPipe() returns and sees
the stop server event signal.
This works with the synchronous ConnectNamedPipe() model.
Here is a complete example (without the child thread) where the main thread is a keyboard loop, ESCAPE to exit, 'S' to stop server.
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#define PIPE_BUFSIZE 512
#define PIPE_TIMEOUT 0
HANDLE hStopServer = 0;
LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";
DWORD CALLBACK PipeServerSync(void *p)
{
HANDLE hPipe = INVALID_HANDLE_VALUE;
printf("* PipeServer Started\n");
for (;;)
{
hPipe = CreateNamedPipe(
lpszPipename,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |
PIPE_READMODE_MESSAGE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
PIPE_BUFSIZE,
PIPE_BUFSIZE,
PIPE_TIMEOUT,
NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
printf("! ERROR %d - Creating Pipe\n",GetLastError());
break;
}
printf("* Waiting for Connection\n");
BOOL fConnected = ConnectNamedPipe(hPipe,NULL);
if (WaitForSingleObject(hStopServer, 0) == WAIT_OBJECT_0) {
printf("- SERVER: STOP\n");
CloseHandle(hPipe);
break;
}
if (fConnected || GetLastError() == ERROR_PIPE_CONNECTED) {
printf("- SERVER: New Client Connection\n");
// create child thread to handle connection
// make sure child disconnects/closes pipe
} else {
CloseHandle(hPipe);
}
}
printf("* PipeServer Exit\n");
return 1;
}
void StopServer()
{
SetEvent(hStopServer);
HANDLE hPipe = CreateFile(lpszPipename,
GENERIC_READ | GENERIC_WRITE,
0, NULL,OPEN_EXISTING, 0, NULL);
if (hPipe != INVALID_HANDLE_VALUE) {
CloseHandle(hPipe);
}
}
void main(char argc, char *argv[])
{
hStopServer = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD tid;
CloseHandle(CreateThread(NULL, 0, PipeServerSync, NULL, 0, &tid));
while (1) {
Sleep(100);
if (_kbhit()) {
int ch = _getch();
if (ch == 27) break;
if (ch == 'S' || ch == 's') StopServer();
}
}
printf("* PAK TO EXIT\n");
_getch();
}
.
- Follow-Ups:
- Re: CloseHandle() hangs on Named Pipe
- From: PaulH
- Re: CloseHandle() hangs on Named Pipe
- References:
- CloseHandle() hangs on Named Pipe
- From: PaulH
- Re: CloseHandle() hangs on Named Pipe
- From: Alexander Grigoriev
- Re: CloseHandle() hangs on Named Pipe
- From: PaulH
- CloseHandle() hangs on Named Pipe
- Prev by Date: Re: The memory can not be written.
- Next by Date: Re: PE verification
- Previous by thread: Re: CloseHandle() hangs on Named Pipe
- Next by thread: Re: CloseHandle() hangs on Named Pipe
- Index(es):
Relevant Pages
|