• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 389
  • Last Modified:

Worker Thread Problem



Hello,

I am creating a worker thread and trying to stop it from my main thread...   When i try to kill/stop the worker thread from the main thread, it is not getting killed, rather it stops at some api or system call..  

In my worker thread i am accessing dlls, handling messages/displays of main thread etc...

In Windows 2000, it is working fine, but the same is giving problem on Windows NT operating system...

Hints or guidelines on solving this would be helpful..


Regards
Bhoopal
0
bhoopal_mp
Asked:
bhoopal_mp
  • 5
  • 3
  • 2
1 Solution
 
chensuCommented:
How do you stop the thread? TerminateThread? No, you should use an event object to signal the worker thread to stop itself. Check out my article at CodeGuru.

Download a File Using URLDownloadToCacheFile
http://www.codeguru.com/internet/urlfile.shtml

Pay attention to the hEventStop event object in the source code.
0
 
bhoopal_mpAuthor Commented:
Hi Chensu,

Thanks for the suggestions... I went through the downloaded code of yours... and i am also doing it in similar way, It is working fine in Windows2000, but not in Windows NT.

In NT it is getting stuck at some API calls i.e i am using
Tree Display..etc..  Any suggestions on how to come out of this would be helpful..

Bhoopal
0
 
chensuCommented:
What API calls? You might want to put some trace messages to see the values of the parameters and return values when it gets stuck.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
bhoopal_mpAuthor Commented:
Hi Chensu,

Please find the portion where it gets stuck...

/******************************
CTreeCtrl* pTree1=(CTreeCtrl*)frame->td->GetDlgItemIDC_TREE1);
tvinsert.item.pszText=frame->td->PmFile;    
tvinsert.hParent=(HTREEITEM)(frame->td->hItem[2]);
HTREEITEM hmyItem=(frame->td->hItem[2]);  
// Delete all of the children of hmyItem whose item data is
// not equal to zero.
if (pTree1->ItemHasChildren(hmyItem))
{
 HTREEITEM hNextItem;
HTREEITEM hChildItem = pTree1->GetChildItem(hmyItem);
while (hChildItem != NULL)  
{
hNextItem = pTree1->GetNextItem(hChildItem, TVGN_NEXT);  
pTree1->DeleteItem(hChildItem);      
hChildItem = hNextItem;  
}
}
pTree1->InsertItem(&tvinsert);

******************************/

and another portion where it gets stuck is...

/*******************************************
BOOL mod=frame->m_Edit.GetModify();
frame->m_Edit.GetWindowText(Text);

******************************************/



In the stack display window it shows, that it has moved to some user32.dll or something of this sort.. i.e basically it gets stuck in some dll..

This is working fine on Windows2000, but creating problem on WindowsNT.

Hints on how to handle the return from thread, if i am using a dll in the thread would be helpful..

regards
Bhoopal
0
 
AndyReedCommented:
Sounds like a message deadlock. Your thread is making calls to GUI elements in your main application. These are serviced by the message queue attached to the main thread. If the main thread is trying to kill the worker thread, and presumably waiting for it to die, you'll get a deadlock.

Check if you have a function in you main application thread which is blocking. If so then your message queue is not being serviced. You need to:
1. Use a non-blocking exit function that signals to the worker thread to exit.
2. Write a handler that checks the running status of the thread. If its still running then post another message to check it again. If its finished then exit the app.
0
 
bhoopal_mpAuthor Commented:


Hi AndyReed,

Thanks for the suggestions, and i too think its goind to a deadlock.

Will you please explain a bit more on the writing the handler part, b'cos currently i am setting the event for the worker thread to exit and waiting for INFINITE time in the main thread for the worker to exit... Apart from this, what are procedures for posting messages etc... Meanwhile i will also try to look into MSDN for the same..

Regards
Bhoopal
0
 
AndyReedCommented:
Yep that'll be it then. You can't do an INFINITE wait if the worker thread sends messages. It would have been safe if your worker thread did only background operations.

What you'll want to do is modify your applications shutdown function to only set the shutdown event and prevent it from actually closing the application. This function should then return (without closing the application) thus continuing to process the message queue.

Lets say you are using a dialog application and that you accept a click event from the OK button to close the app. Normally the hander would look like this:

void CTest1Dlg::OnOK()
{
     CDialog::OnOK();
}

However you only want the base class OnOK to be called if the worker thread has ended. If not then you need to wait a while until it does. But you don’t want this function to hang the main thread. If you define your own message handler (MyCloseDown) to respond to your own user defined message (WM_MY_CLOSE_DOWN_MSG) you can post these messages to the main queue. Using PostMessage adds the message to the applications message queue but does not wait for it to be processed.

void CTest1Dlg::OnOK()
{
     m_shutdown_event.SetEvent();

     PostMessage( WM_MY_CLOSE_DOWN_MSG );
}

You then need to write a handler for the WM_MY_CLOSE_DOWN_MSG message. This should check the running state of the thread, close the application if the thread has completed or call itself if not.

afx_msg LRESULT CTest1Dlg::MyCloseDown( WPARAM, LPARAM )
{
     if( WaitForSingleObject( hThreadHandle, 0 ) == WAIT_OBJECT_0 )
     {
          // Thread has completed
          CDialog::OnOK();
     }
     else
     {
          // Thread is still running
          PostMessage( WM_MY_CLOSE_DOWN_MSG );
     }

     return 0;
}

You’ll need to define the message:

#define WM_MY_CLOSE_DOWN_MSG     WM_USER + 1

and add an entry to the message map:

BEGIN_MESSAGE_MAP(CTest1Dlg, CDialog)
     //{{AFX_MSG_MAP(CTest1Dlg)
     ON_MESSAGE(WM_MY_CLOSE_DOWN_MSG, MyCloseDown)
     //}}AFX_MSG_MAP
END_MESSAGE_MAP()
0
 
bhoopal_mpAuthor Commented:

Hi AndyReed,

Thanks for the good hints and suggestions given... I will check this at the earliest..

Bhoopal
0
 
AndyReedCommented:
I believe this to be a correct and detailed answer. Please respond and award points accordingly.

Regards,
Andy.
0
 
bhoopal_mpAuthor Commented:


Sorry for the delay, i believe, i had accepted...

Anyway doing it again...
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now