Weird wxThread problem with Delete() and Wait() under WXMSW

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
darryl242
In need of some credit
In need of some credit
Posts: 6
Joined: Tue Aug 16, 2005 10:14 pm

Weird wxThread problem with Delete() and Wait() under WXMSW

Post by darryl242 » Tue Aug 16, 2005 10:39 pm

wx-masters,

I've used wxThread with Windows before (wx2.4) without a problem. I'm working on a new project using wx2.6.1 and I'm having a problem where Delete() and Wait() are returning "invalid handle". I have put together a very small example that illustrates the problem (at least on my setup).

OS: Windows XP Home Edition Version 2002 Service Pack 2
Compiler: Visual C++ 6.0 Service Pack 5
Release build flags: NDEBUG,WIN32,_WINDOWS,WINVER=0x0400,UNICODE,_UNICODE
Libraries: kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib winmm.lib wsock32.lib

I can attach my wx setup.h if required (it's pretty much stock though).

The example test code:

Code: Select all

#include <wx/setup.h>
#include <wx/wx.h>
#include <wx/thread.h>
#include <wx/log.h>

typedef void *ExitCode;

class myThread : public wxThread
{
public:
	myThread() : wxThread(wxTHREAD_JOINABLE) {}
	ExitCode Entry();
};

ExitCode myThread::Entry()
{
	while(!TestDestroy())
	{
		wxLogMessage(wxT("thread tick."));
		Sleep(1000);
	}

	return NULL;
}

class myFrame : public wxFrame
{
public:
	myFrame();
	~myFrame();

private:
	myThread *thread;
};

myFrame::myFrame() : wxFrame(NULL, wxID_ANY,
	wxT("Frame"), wxDefaultPosition, wxSize(320, 240))
{
	thread = new myThread();

	if(thread)
	{
		wxThreadError error;

		if((error = thread->Create()) == wxTHREAD_NO_ERROR)
			error = thread->Run();

		if(error == wxTHREAD_NO_ERROR)
			wxLogMessage(wxT("thread started."));
		else
			wxLogMessage(wxT("thread creation error."));
	}

	Centre(); Show(true);
}

myFrame::~myFrame()
{
	if(thread)
	{
		wxLogMessage(wxT("thread->Delete()..."));
		thread->Delete();
		wxLogMessage(wxT("thread->Wait()..."));
		thread->Wait();
		wxLogMessage(wxT("delete thread..."));
		delete thread;
	}

	wxLogMessage(wxT("frame destroyed."));
}

class myApp : public wxApp
{
public:
	bool OnInit();
	int OnExit();

private:
	wxLogWindow *log;
};

DECLARE_APP(myApp)
IMPLEMENT_APP(myApp)

bool myApp::OnInit()
{
	log = new wxLogWindow(NULL, wxT("Log"), true, false);
	myFrame *frame;
	if(!(frame = new myFrame)) return false;
	SetTopWindow(frame);

	return true;
}

int myApp::OnExit()
{
	return wxApp::OnExit();
}
The output from the above code:

Code: Select all

18:16:31: thread started.
18:16:31: thread tick.
18:16:32: thread tick.
18:16:33: thread tick.
18:16:34: thread tick.
18:16:35: thread->Delete()...
18:16:35: thread->Wait()...
18:16:35: Error: Can not wait for thread termination (error 6: the handle is invalid.)
18:16:35: Error: Can not terminate thread (error 6: the handle is invalid.)
18:16:35: delete thread...
18:16:35: frame destroyed.
Question is why do I get "handle is invalid"... This sample code works fine under wx2.6.1/Linux. Any ideas?

Thanks :)

User avatar
Ryan Norton
Moderator
Moderator
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Re: Weird wxThread problem with Delete() and Wait() under WX

Post by Ryan Norton » Wed Aug 17, 2005 12:07 pm

darryl242 wrote:Question is why do I get "handle is invalid"... This sample code works fine under wx2.6.1/Linux. Any ideas?

Thanks :)
You should just be able to call Wait() - the thread is always dead on MSW after delete IIRC.
[Mostly retired moderator, still check in to clean up some stuff]

darryl242
In need of some credit
In need of some credit
Posts: 6
Joined: Tue Aug 16, 2005 10:14 pm

Re: Weird wxThread problem with Delete() and Wait() under WX

Post by darryl242 » Wed Aug 17, 2005 2:18 pm

Ryan Norton wrote: You should just be able to call Wait() - the thread is always dead on MSW after delete IIRC.
Oh, ok... Is that not what I'm doing though? What would you differently here? I'm calling Delete() then Wait()... Both of these result in errors. The interesting part is that Delete() actually does something right because the thread does break at TestDestroy(). Nothing ever works for me under Windows :(

Code: Select all

                thread->Delete();
                thread->Wait();
                delete thread; 
Thanks...

darryl242
In need of some credit
In need of some credit
Posts: 6
Joined: Tue Aug 16, 2005 10:14 pm

Post by darryl242 » Wed Aug 17, 2005 6:58 pm

Strange... I just discovered that if I call Delete() but not Wait()... the "handle invalid" error messages go away. I guess I'll leave my code like that as it seems to work. Does anyone know if this is a bug or something specific to Windows? Should I update the wxThread entry on wxWiki? There is no mention of this behaviour anywhere that I've read.

Code: Select all

        thread->Delete();
        //thread->Wait(); BAD
        delete thread;
Thanks again - now I can move along...

User avatar
Ryan Norton
Moderator
Moderator
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Post by Ryan Norton » Wed Aug 17, 2005 10:28 pm

darryl242 wrote:Strange... I just discovered that if I call Delete() but not Wait()... the "handle invalid" error messages go away. I guess I'll leave my code like that as it seems to work. Does anyone know if this is a bug or something specific to Windows? Should I update the wxThread entry on wxWiki? There is no mention of this behaviour anywhere that I've read.

Code: Select all

        thread->Delete();
        //thread->Wait(); BAD
        delete thread;
Thanks again - now I can move along...
No - you need to call Delete OR Wait - both of them eventually delete the thread handle (but not the wxThread in the case of joinable threads).

Wait IIRC is the same as delete except it returns the exit code of the thread while Delete does not and its only for joinable threads
[Mostly retired moderator, still check in to clean up some stuff]

darryl242
In need of some credit
In need of some credit
Posts: 6
Joined: Tue Aug 16, 2005 10:14 pm

Post by darryl242 » Thu Aug 18, 2005 12:41 am

Yes, you are correct... My tests confirmed that Wait() or Delete() work the same (with the exception you pointed out). Linux pthreads doesn't cause the same error, that's why I thought I had a clue :p

Thanks again!

Post Reply