Re: CloseHandle() hangs on Named Pipe

Tech-Archive recommends: Fix windows errors by optimizing your registry



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();
}



.



Relevant Pages

  • asynchronously writing to a file, a cheap way?
    ... performance when the processing server is running. ... end of the pipe doesn't need to be running. ... remove "nospam" change community. ... I you already have a thread pool or IOCP that you can use t handle the ...
    (microsoft.public.win32.programmer.kernel)
  • Re: asynchronously writing to a file, a cheap way?
    ... your typical asynchronous route for writing to a file, ... performance when the processing server is running. ... end of the pipe doesn't need to be running. ... I you already have a thread pool or IOCP that you can use t handle the ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Service: Datenaustausch zwischen Service und Desktop zulassen
    ... einfach ist als Pipe). ... Das hoert sich fuer mich so an als redest Du einer Loesung das Wort ... Empfaenger, der so tut als ob er der legitime named Pipe Server sei, ... named-Pipe-Server-End den Service impersonated und somit seine eigenen ...
    (microsoft.public.de.vc)
  • Multithreaded pipe server, deadlock problem
    ... I'm working on a multithreaded pipe server. ... The primary thread create name pipes and if a client is connected, it then create a thread and let the thread procedure "InstanceThread" process the clients. ... // Marker 0 ...
    (microsoft.public.win32.programmer.kernel)
  • Re: CloseHandle() hangs on Named Pipe
    ... pipe server? ... functions vs specific pipe functions where the handling are not 100% ... Use a StopServer() "Client connection" to wake up the server and stop ...   - MainThread: Calls StopServer ...
    (microsoft.public.win32.programmer.kernel)