Is it safe to "double-close" a handle using CloseHandle?
Asked Answered
A

3

6

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).

Armandarmanda answered 5/7, 2010 at 11:3 Comment(1)
What "shared handle" are you referring to? Each process should be creating and closing its own handle to the (same) pipe. How does a handle end up getting shared? Alas, the answer is "just don't", but that's because the handle shouldn't be getting shared at all.Curricle
G
13

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.

Gomez answered 5/7, 2010 at 11:22 Comment(1)
+1, Also a handle can be reused for object of any kind - maybe mutex, maybe something else. Doing CloseHandle() twice could have surprising consequences.Subclass
M
4

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.

Michell answered 5/7, 2010 at 12:0 Comment(1)
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).Armandarmanda
S
1

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.

Suavity answered 5/7, 2010 at 18:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.