tags:

views:

67

answers:

3

What are the implications of calling CloseHandle more than once?

The docs say "you shouldn't" but I think I have a realistic case with named pipes where a handle might be closed externally (See end of post).

CloseHandle throws an exception in debug mode in this case, which suggests to me the developers think this is serious, but the docs aren't exactly clear.

(Polite request: Please avoid the answer "just don't!" :-). Of course one should avoid closing a handke more than once, and of course there are good techniques to help with this: I'm just interested in what happens if you don't).

I've heard some people suggest that if the handle was quickly reused by the OS you might end up closing another, different handle.

Is this likely?

How does Windows choose handle IDs?

Is there any guarantee about how regularly a handle value will be reused?

(e.g. TCP ensures that a port number cannot be reused within a certain timeframe).

Can you close handles accross handle types? E.g., could I be thinking I'm closing a pipe but end up closing an Event?

Thanks!

John

(Context to this: I'm using named pipes in a client/server model. It seems to me very difficult to ensure that exactly one party is guaranteed to close the handle, e.g. in process crash/killed case. Perhaps I'm wrong, but certainly the MSDN sample code seems to my mind to allow the client to close the shared handle, and then when the server tries to close it, it is already closed).

+6  A: 

Simple enough to check:

HANDLE h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
CloseHandle(h);
h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);

In my WinXP x64 this produced:

2E8
2E8

So there you have it.
Unlike TCP ports, handles are recycled immediately.

Repeat this experiment with your favorite API or any mix thereof.

shoosh
+1, Also a handle can be reused for object of any kind - maybe mutex, maybe something else. Doing CloseHandle() twice could have surprising consequences.
sharptooth
+3  A: 

You probably have the wrong mental image of a pipe. It has two ends, each represented by a different handle. Yes, CloseHandle has to be called twice to make the pipe instance disappear. But since they are different handles, that can never cause any problem. Also note that handle instances are process specific. Even if they have the same value in both processes, they do not reference the same pipe endpoint.

Hans Passant
Hmm maybe I have misunderstood. But I've definitely seen issues where the client to the pipe closes the pipe, and the server then throws a "invalid handle" exception (in debugging mode).
John
I dunno, could just be a bug in the server code when it keeps using the handle even after it closed it because the pipe got disconnected.
Hans Passant
A: 

There are two things that could happen:

  1. You close a handle opened by some other code. That probably doesn't affect your code but it's likely to be catastrophic for the other code.
  2. If you're running with a debugger attached, you crash your application because the OS will raise an exception when it detects an invalid handle being closed.

Neither of these is particularly attractive IMHO.

Larry Osterman