Why does the debugger stop execution and give an error when WaitForSingleObject() is called on a closed HANDLE?? when I run my program outside of the VS2010 IDE, WaitForSingleObject(invalid handle) just returns WAIT_FAILED like its supposed to. Is there anything actually wrong with calling it on an invalid handle?

Recommended Answers

All 3 Replies

Are you maybe executing a release build outside of VS, and inside a debug build? In that case there could be an assertation in the function.

The documentation does not state that the handle must be valid... it does state that if the handle is closed while the wait is not satisfied, the function behavior is undefined...

What is the return of GetLastError() after the WAIT_FAILED return? It should probably be something like INVALID_HANDLE.

In any case... why are you calling this function with an invalid handle anyway? ;)

I'll just start over and state my whole problem:

I am writing a file transfer program that uses a separate thread to send the file

here is some pseudo of my data sending thread:

DWORD WINAPI SendDataProc(LPVOID lpParam)
{
	OpenFile();
	ReadChunkFromFile();
	
	//incase the cancel event is triggered from outside of the thread
	while(WaitForSingleObject(evtCancelTransfer, 0) != WAIT_OBJECT_0)
	{
		//wait for socket to be ready
		WaitForSingleObject(evtSocketReady, TIMEOUT);
		
		if(SendChunk() == BLOCKED)
		{
			ResetEvent(evtSocketReady);
			continue;
		}
		
		if(EOF)
		{
			CloseFile();
			break;
		}
		else
		{
			ReadNextChunk();
		}
	}
	return 1;
}

now, this thread can either return because the file transfer has completed, or it can return because evtCancelTransfer has been triggered.

I need to:
1) be able to detect whether or not a file transfer is in progress
2) be notified when a transfer ends
3) end the transfer properly at the users command

As far as the transfer ending on its own, I figured that I could put this right at the end of the thread before it returns.

PostMessage(tdata.hOwner, WM_SENDCOMPLETE, NULL, NULL);

then when handling that message, to make sure that the thread is finished,

case WM_COMPLETE:
	WaitForSingleObject(hThread, INFINITE);
	DoGarbageCleanupForThread();

all this would be fine and dandy if there wasn't the possibility of the transfer having to be canceled in the middle.

because if use SetEvent(evtCancelTransfer) to allow the thread to finish properly, when would I do the cleanup? That is the problem. In the lines following the cancellation, I could not safely use the resources of that thread or file transfer, because WM_SENDCOMPLETE has not yet been called to do the cleanup.

I am confused about how to handle this =/ Its kind of a paradox...

depending on the situation, the time that it may take for my thread to close is unpredictable. So if I poll, find out the thread is active, there is the chance that

A) SetEvents(eventCancel) will be set after the thread has returned and that handle has already been closed. The handle may even be null if the garbage cleanup has been done already.

B) WaitForSingleObject(hThread) will be called after the thread has returned, and its handle has been deleted or closed

I don't see any way that these two things could be avoided...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.