Page 1 of 1

How to close Joinable threads

Posted: Mon Aug 17, 2009 2:43 pm
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?

Posted: Mon Aug 17, 2009 5:09 pm
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.

Posted: Tue Aug 18, 2009 9:27 am
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;
}

Posted: Tue Aug 18, 2009 11:45 am
by MuhammadSohail
Do i use wxMutex or wxCriticalSection??

Posted: Tue Aug 18, 2009 1:10 pm
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 ;)

Posted: Wed Aug 19, 2009 3:24 pm
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;
}

Posted: Wed Aug 19, 2009 5:15 pm
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.