Discussion:
WaitForSingleObject on an event Handle leaks a new handle!
(too old to reply)
Mechi
2010-05-03 13:16:41 UTC
Permalink
Raw Message
Hi!
I create and call 2 threads (camera and Display) and each thread has
an DeadEvent which is set when the thread exits. This adds 4 new
Handles.
I'm using ProcessExplorer to monitor the handles in my application.
Every time the threads are opened and then closed, there is still one
handle that is not closed down - a leak. I traced that handle to the
WaitForSingleObject on the DeadEvent of the first thread. Has anyone
experienced this?
Any ideas? Code below...
Thanks,
Mechi


To be more specific:

// creating the threads - 4 new handles
if (!m_hCameraDead) m_hCameraDead = CreateEvent(NULL, TRUE, FALSE,
NULL);
if (!hCameraThread)
hCameraThread = (HANDLE)_beginthreadex(NULL,0,Camera_Thread,
this, 0, 0);

if (!m_hDisplayDead) m_hDisplayDead = CreateEvent(NULL, TRUE, FALSE,
NULL);
if (!hDisplayThread)
hDisplayThread = (HANDLE)_beginthreadex(NULL, 0,Display_Thread,
this, 0, 0);

// checking to see that the CameraThread didn't exit right away - adds
an extra handle
if (WaitForSingleObject(m_hCameraDead, 3) != WAIT_TIMEOUT)
{
CloseHandleEx(&hCameraThread);
}
Leo Davidson
2010-05-03 15:00:29 UTC
Permalink
Raw Message
Post by Mechi
Hi!
I create and call 2 threads (camera and Display) and each thread has
an DeadEvent which is set when the thread exits.  This adds 4 new
Handles.
You're creating four handles (two thread handles and 2 event handles).

Are you closing all four handles in all cases?

What is CloseHandleEx? (I don't think that's a standard Win32
function, unless Google & MSDN are failing me.) Is it supposed to take
a pointer to a handle or is that an error?

As an aside, do you even need the two event handles? If you want to
wait for a thread to finish then it's better to wait on the thread
handles themselves. If you set an event just before your thread exits
then other code may think the thread has exited when it is still doing
work (e.g. running object destructors). Threads have not finished
until *after* the closing "}" of their thread procs, which is where
the thread handles will become signalled.
Mechi
2010-05-04 10:22:48 UTC
Permalink
Raw Message
Post by Leo Davidson
What is CloseHandleEx? (I don't think that's a standard Win32
function, unless Google & MSDN are failing me.) Is it supposed to take
a pointer to a handle or is that an error?
All handles are initialized to NULL.
CloseHandleEx - helps me close without making code messy and checking,
etc.

void CloseHandleEx(HANDLE *hObject)
{
BOOL ret;
char msg[100];
if (*hObject != NULL)
{
ret = CloseHandle(*hObject);
if (!ret)
{
DWORD err = GetLastError();
sprintf_s(msg, 100, "couldn't close err=%d", err);
MessageBox(NULL,"Closehandle error", msg, MB_OK);
}
*hObject = NULL;
}
}
Post by Leo Davidson
As an aside, do you even need the two event handles? If you want to
wait for a thread to finish then it's better to wait on the thread
handles themselves. If you set an event just before your thread exits
then other code may think the thread has exited when it is still doing
work (e.g. running object destructors). Threads have not finished
until *after* the closing "}" of their thread procs, which is where
the thread handles will become signalled.
Thanks! I'll look into getting rid of the 2 extra Event handles.
Thanks again,
Mechi
Mechi
2010-05-04 12:55:08 UTC
Permalink
Raw Message
Post by Leo Davidson
As an aside, do you even need the two event handles? If you want to
wait for a thread to finish then it's better to wait on the thread
handles themselves. If you set an event just before your thread exits
then other code may think the thread has exited when it is still doing
work (e.g. running object destructors). Threads have not finished
until *after* the closing "}" of their thread procs, which is where
the thread handles will become signalled.
Thanks!  I'll look into getting rid of the 2 extra Event handles.
I got rid of the handles and used the following code (thanks to Code
Project) to check when thread:

DWORD dwRet;

do
{
dwRet = WaitForSingleObject(hDisplayThread, INFINITE);
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));

Thanks for the hint!

I'm still having the problem of extra handles being accessed and not
released when the thread exits.
To make matters worse, the same code compiled on my colleagues
computer doesn't have these "extra" handles. And conversely, his code
on my computer still produces the extra handles while my compiled
version on his computer does not!!!

Why would two Windows XP machines with the same OS and Service packs
show different
results?

When I debug, before the "extra" handle is created (using Process
Explorer), I stop all three threads and step through each. In the
Process Explorer, I can even see the Handle ID and the Object
address. All the Handles have the same Object address. How can i
trace the Handle ID to find out who/what and where is the handle being
created????

Thanks!
Mechi
David Lowndes
2010-05-03 15:04:05 UTC
Permalink
Raw Message
Post by Mechi
I'm using ProcessExplorer to monitor the handles in my application.
Every time the threads are opened and then closed, there is still one
handle that is not closed down - a leak. I traced that handle to the
WaitForSingleObject on the DeadEvent of the first thread.
So, where do you call CloseHandle for the m_hCameraDead handle?

Dave
Mechi
2010-05-04 15:21:21 UTC
Permalink
Raw Message
Post by David Lowndes
Post by Mechi
I'm using ProcessExplorer to monitor the handles in my application.
Every time the threads are opened and then closed, there is still one
handle that is not closed down - a leak.  I traced that handle to the
WaitForSingleObject on the DeadEvent of the first thread.
So, where do you call CloseHandle for the m_hCameraDead handle?
Dave
I take care of closing it after the thread exits.
Thanks!
Mechi

Loading...