Re: Threading problem



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: Design question
    ... > call this class Storage. ... > will call DisplayPanel) with several JTextFields, JComboBoxes, JPanel's ... > like a pointer would be really useful here, so that I could just pass ... for all object parameters. ...
    (comp.lang.java.programmer)
  • Re: Fragmented memory compaction ???
    ... pointer" class where every access to the object is dereferenced via an indirect pointer ... Compaction and garbage collection are not at all the same, ... a contiguous block of allocated storage, and a contiguous block of free ... even a simple, single-threaded storage allocator (I've done it, and written a book chapter ...
    (microsoft.public.vc.mfc)
  • Re: Fragmented memory compaction ???
    ... pointer" class where every access to the object is dereferenced via an indirect pointer ... Compaction and garbage collection are not at all the same, ... a contiguous block of allocated storage, and a contiguous block of free ... even a simple, single-threaded storage allocator (I've done it, and written a book chapter ...
    (microsoft.public.vc.mfc)
  • Re: Referencing an object via variable.
    ... >the pointer you need at the start. ... Also one could store the reference to objects in the Tag property of some ... out of storage. ... display) than the object from the string. ...
    (alt.comp.lang.borland-delphi)