Re: Threading problem

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



You can alwasy ShowWindow(SW_HIDE) to hide the form; you just can't let it be destroyed as
long as there is any thread depending on it. You really have to keep it live until all
the threads that depend on it go away. Your analysis about the storage being freed is the
fundamental problem, and yes, you're hosed.
joe


On Tue, 4 Jul 2006 17:00:45 -0500, "Eric Margheim" <NOSPAM***eric@xxxxxxxxxxxxx***NOSPAM>
wrote:

****
Note that if you manage to delete the form while this loop is running,
then
this->GetSafeHwnd() is not defined, and might return anything.
GetSafeHwnd() essentially
does very little, and doesn't check to see if this() is actually a valid
pointer (it works
correctly if this is NULL, but if this is a pointer to free storage on the
heap it works
just fine!) So you have a fundamental race condition.

Key here is that you must not allow the form to be closed if there are any
active threads.
This means you must intercept the OnClose handler and defer its actual
working, e.g.,

void CMyForm::OnClose()
{
if(threads_are_running)
{ /* have to wait */
closing = TRUE;
return;
} /* have to wait */
CParentClass::OnClose();
}
now you can set it up so that it disables all controls (e.g., I would call
my
updateControls() method which would notice the closing boolean is now TRUE
and disable all
the controls) and the thread loop would say

for(...process recordset)
{
if(closing)
{ /* shut thread down */
break;
} /* shut thread down */
}

PostMessage(UWM_THREAD_DONE);

then the thread-done handler looks like

LRESULT CMyForm::OnThreadDone(WPARAM, LPARAM)
{
if(closing)
CParentClass::OnClose();
return 0;
}

[note that you might want to do more than this bare outline, this is just
a sketch]

if you have many threads, the simplest way to handle this is do an
InterlockedIncrement of
the thread counter when you start a thread, and an InterlockedDecrement as
each thread
sends its completion notification, and close the form when the reference
count goes to
zero

LRESULT CMyForm::OnThreadDone(WPARAM, LPARAM)
{
long count = InterlockedDecrement(&threadcount);
if(closing && count == 0)
CParentClass::OnClose();
return 0;
}

this is an asynchronous shutdown, which is pretty much mandatory if you
can't abort the
worker thread (such as it is blocked on doing the database access).

Actually, I'm amazed it ever worked; it is probably just good luck that it
gave the
illusion of working. Sounds like VS8 has a more stringent protocol on its
storage
allocator which makes the existing error a bit more obvious.
joe


If you recall this is one of the issues I was dealing back years ago when
you came to visit. There has to be a way to handle this. From a end user
perspective it's really bad to force that form to be open. I think I tried
hiding the window while it's cleaning up so from the user perspective it is
closed. Is that what you are alluding to? Perhaps I should set a flag in
the thread instead of relying on the GetSafeHwnd() call. I am nulling out
the pointer to the parent wnd, perhaps I should be referencing that
instead.... or is the problem because the memory space used for the
function is part of the CFormView class and once it's closed I'm hosed?

Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: The Zen nature of a Delphi database application
    ... results directly to UI controls, then write data from the controls to ... then write data back from the modified objects to the DB for storage? ... I load the whole contents of the database into my business objects, ... I have dreamt of the perfect OO database application framework ...
    (comp.lang.pascal.delphi.misc)
  • Re: Difference between Char* ptr and char arrCh []
    ... Is there a difference in storage of global char* and char* inside a ... The pointer is stored in automatic storage. ... and the pointer globalCh must be writable. ...
    (comp.lang.c)
  • Re: C programming question
    ... they occupy the same storage. ... is associate a pointer with the new structure and assign a value to the pointer that ... LABELIDA DS CL4 ... to allocate any storage for the "cms_label" structure, ...
    (Debian-User)
  • Re: A question about identifiers
    ... object and pass the pointer around. ... In C you can't form a pointer to an object with register storage ... 'register' object in memory, you still can't take & of it. ... The defining characteristic of objects is storage. ...
    (comp.lang.c)
  • Re: Once again trying to use the SSL ported to VMS
    ... C on VMS. ... Apparently, SSL_CTX_newallocates some storage, and returns ... I'm assuming is a pointer to the storage. ...
    (comp.os.vms)