How to close Joinable threads Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
MuhammadSohail
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jun 17, 2005 1:53 pm
Location: Germany
Contact:

How to close Joinable threads

Post by MuhammadSohail »

Trying to close the GUI application immediately after calling the close function of the UDP thread.

GUI application is crashed. After debugging

Code: Select all

BugReporter.exe!wxMutexInternal::LockTimeout(unsigned long milliseconds=0xffffffff)  Zeile 232 + 0x7	C++
 	BugReporter.exe!wxMutexInternal::Lock()  Zeile 190 + 0x11	C++
 	BugReporter.exe!wxMutex::Lock()  Zeile 45	C++
 	BugReporter.exe!UDPMessageThread::close()  Zeile 95	C++
 	BugReporter.exe!UDPMessageThread::~UDPMessageThread()  Zeile 75	C++
 	BugReporter.exe!UDPMessageThread::`scalar deleting destructor'()  + 0x14	C++
 	BugReporter.exe!BugReporterApplication::stopUDPThread()  Zeile 1697 + 0x25	C++


wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds)
{
--> DWORD rc = ::WaitForSingleObject(m_mutex, milliseconds);
    if ( rc == WAIT_ABANDONED )
    {
My close function which is called in the destructor of the UDPMessageThread class

Code: Select all

void UDPMessageThread::close()
{
	d_accessDataMutex.Lock();
	d_run=false;
	d_accessDataMutex.Unlock();

	// Wait till thread deletes itself
	ExitCode exitCode ;
	if (IsRunning())
	{
		exitCode = Wait();
		
	cout << "exit code: " << exitCode << endl;
	}

	d_accessDataMutex.Lock();
	if (d_socket!=NULL)
	{
		d_socket->Destroy();
		d_socket=NULL;
	}
	d_accessDataMutex.Unlock();
}
Please someone help me how to delete or close the Joinable thread and immediately closing the main application?
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

You're using Wait() to terminate a joinable thread, which is a good thing, but are you making use of TestDestroy() into your thread's loop ? If no, then wait() is just no use.
MuhammadSohail
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jun 17, 2005 1:53 pm
Location: Germany
Contact:

Post by MuhammadSohail »

How do i use the TestDestroy() function. Here is my Entry code

Code: Select all

wxThread::ExitCode UDPMessageThread::Entry()
{
       MessageBase::version = 2;

	d_accessDataMutex.Lock();
	PingMessage ping(0, d_currentUser);
	ping.createByteArray(ping.rawData, true);
	d_accessDataMutex.Unlock();

	while (d_run && d_socket != NULL)
	{
		d_accessDataMutex.Lock();
		try
		{
			if (d_sendPing && d_socket->IsOk())
			{
				d_socket->SendTo(d_targetAddress, &ping.rawData[0], (wxUint32)ping.rawData.size());
			}
			else
			{
			cout << "[UDPMessageThread] socket is not ok .... shut down UDPMessageThread." << endl;
				d_accessDataMutex.Unlock();
				break;
			}
		}
		catch (...)
		{
			cout << "[UDPMessageThread] EXCEPTION Unbehandelte Ausnahme." << endl;
			d_accessDataMutex.Unlock();
			break;
		}
		d_accessDataMutex.Unlock();
		wxThread::Sleep(1000);
	}

	return NULL;
}
MuhammadSohail
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jun 17, 2005 1:53 pm
Location: Germany
Contact:

Post by MuhammadSohail »

Do i use wxMutex or wxCriticalSection??
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

Just add some

Code: Select all

!TestDestroy()
into your while loop:

Code: Select all

while ( d_run && d_socket != NULL && !TestDestroy() ) { ... }
.

Regarding you mutex/critical_section question, you can answer yourself knowing if either you need real synchronisation (-> mutex) or just forbidding multiple access (-> critical section).

By the way: the "break" into your "catch" is no use, and the other "break" into your "else" is quite ugly. Try to rewrite it properly ;)
MuhammadSohail
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jun 17, 2005 1:53 pm
Location: Germany
Contact:

Post by MuhammadSohail »

I have just modified my close function ,without Wait() function, its working

Code: Select all

if (IsRunning())
{
   while (IsRunning())
   {
	Sleep(100);
    cout << "UDPMessageThread::close(): IsRunning check"       
    << endl;
  }
  
   //exitCode = Wait();
  //cout << "UDPMessageThread::close() " << "exit code: " << 
  //exitCode << endl;
}
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

IsRunning() is not really meant to be called from the safe context itself.
Maybe is your problem solved, but i think you really should have interest into thread deletion if you want to learn to code properly with wxwidgets framework.
Post Reply