Reputation: 155
I have a GUI application with MFC. I'am lauching thread to process some data using AfxBeginThread(). And i've got problem accessing to main dialog in thread:
Through this struct I'am passing main dialog handler and pointer to main dlg object to thread. But at strcpy() line debugger stops and shows pDlg->0x430f0020 {CTabDlg hWnd=???}
typedef struct {
LPVOID myHandle;
LPVOID myPointer;
} sParamData;
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s;
s = (sParamData*)Param;
HWND hMainHandle = (HWND) (*s).myHandle;
CtabDlg* pDlg = (CtabDlg*)(*s).myPointer;
strcpy(apikey, pDlg->m_sVar);
...
}
I tried both XP and Windows 7 OS. In XP it always crashes, but in Seven it works. This is how i pass the struct to the thread:
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
Thank you for your time!
Upvotes: 0
Views: 1090
Reputation: 5230
If your code is exactly as your real case then here you are declaring a local sParamData and passing its address to thread. This gives a race condition: s can go out of scope before the thread start execution, (or reaches the point where its content is copied).
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
The simplest workaround is probably allocate s on heap and delete it in thread after its content has been copied.
Like this:
sParamData *s = new sParamData ;
s->myHandle = (HWND)GetSafeHwnd();
s->myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
And then, inside the thread
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s = (sParamData*)Param;
HWND hMainHandle = (HWND) s->myHandle;
CtabDlg* pDlg = (CtabDlg*)s->.myPointer;
// assuming s will no longer be used you can delete it here
delete s ;
Upvotes: 3