2010-12-03 32 views
0

J'ai quelques (plus) questions sur l'appel de CloseHandle.CloseHandle confusion - Dois-je appeler CloseHandle sur plusieurs "copies" d'un descripteur?

Ainsi, the SO citizens have spoken, and you must always close a handle.

Question 1

J'ai écrit l'extrait de code suivant dans un destructor:

HANDLE handles[] = { m_hGrabberThread, m_hCtrlThread, m_hErrDispatchThread }; 
int nNumHandles = sizeof(handles)/sizeof(handles[0]); 

for(int n = 0; n < nNumHandles; n ++) 
    CloseHandle(handles[n]); 

Le code ci-dessus valide, ou dois-je appeler CloseHandle() sur chaque variable membre de la poignée individuellement ?

par exemple.

if(m_hCtrlThread != INVALID_HANDLE_VALUE) 
    CloseHandle(m_hCtrlThread); 

Je suppose que cette question est liée (vaguement) à la question 2 ...

Question 2

J'ai une classe qui crée un handle d'événement:

HANDLE hEventAbortProgram = CreateEvent(NULL, TRUE, FALSE, NULL); 

Ce descripteur est partagé entre les autres threads d'autres objets.

En partageant la poignée, je veux dire:

objectB.m_hEventAbort = objectA.m_hEventAbort; 

Les fils de chaque objet sera alors faire quelque chose comme:

while(WaitForSingleObject(m_hEventAbort, 0) == WAIT_TIMEOUT) {...} 

Lorsque l'événement est signalé, tous les threads sortiront.

Ma question est la suivante: Dois-je appeler CloseHandle sur chaque copie de la poignée, ou juste une fois dans mon objet principal "parent"?

Je suppose que je demande: les références de poignées sont-elles comptées lorsqu'elles sont copiées?

Je sais qu'un handle est seulement un typedef pour un void *, donc mon instinct dit non, j'ai juste besoin de l'appeler une fois par handle.

+0

Je doute que l'appel 'CloseHandle (INVALID_HANDLE_VALUE)' fasse du mal, alors pourquoi s'embêter à le vérifier? – ruslik

+1

Jetez un coup d'œil à http://stackoverflow.com/questions/1562421/making-a-handle-raii-compliant-using-shared-ptr-with-a-custom-deleter; vous pourriez être en mesure d'utiliser Boost pour la tenue de livres. – MSalters

Répondre

2

À la question 2: Le nombre d'appels à CloseHandle doit équilibrer le nombre d'appels pour gérer les fonctions de création. Si vous affectez simplement un descripteur à une autre variable HANDLE, vous n'avez pas créé de nouvelle poignée - les deux poignées ont la même valeur. Vous pouvez partager la valeur du handle autant que vous le souhaitez, mais un seul objet doit finalement fermer le handle.

Si vous ne pouvez pas garantir l'ordre de destruction des objets partageant une poignée; vous pouvez utiliser DuplicateHandle pour créer des poignées supplémentaires à partir d'une poignée existante.Chaque poignée supplémentaire créée devrait être fermée, et l'objet sous-jacent la référence des poignées ne serait libéré que lorsque toutes les poignées seraient fermées.

0

Réponse 1 Votre code est valide. Mais je vous suggère de vérifier si la poignée "sous" l'index actuel est un handle valide.

Réponse 2 Si vous partagez cette poignée sans doublon et sans comptage de référe et ainsi de suite, il vous suffit de fermer l'un temps et il sera invalide.

+0

sur le point 1, oui, c'est seulement pseudocode;) –

+1

? ... Juste une suggestion ^^ ... Est-ce que cela répond à vos questions? :) – Incubbus

+0

oui, merci Incubbus! –