DAO 'multithread' - interesting problem
David Ohlssen -- DAVIDO@COMMERCE.CTECH.AC.ZA
Tuesday, May 14, 1996
NT 4.0.1234 VC++4.0
I know DAO is not multithread re-entrant. (Yet? Ever?) I have a
worker thread that mans the comms port and has to write records to
disk as they come in. The user app has to display some of that
data, perhaps older records, but according to user request. I have
made a second worker thread that has sole control over the DAO db
recordsets. Both the comms thread and the CView supply and retrieve
data by asking the db thread via the pointers. The communication is
via flag-pointers and data in the CWinApp class, located via
AfxGetApp(). The db thread opens the database and closes it when
there is a signal from exitinstance. Exit instance waits for the
threads to signal completion then calls the default. There are
judicius Sleep calls in every waiting situation.
When exitinstance calls the default there is an access violation. I
have traced and found that it calls AfxDaoTerm() which crashes in
the call to RemoveAll() workspaces. The actual crash is because of
m_pBlocks containing zero and being used as a pointer in MFC code.
Is this because the db thread opened the database and we are letting
CWinApp clean up (the main app thread)? It can't be, because the
pointer to AfxDaoTerm is set for the main thread otherwise it wouldnt
be called. I NEED the separate db thread, to provide rapid service to
the comms thread regardless of user activity such as listbox fill.
I have tried using the CDaoDatabase class on the stack and heap and
in the app. I have tried a 5 second sleep before calling the
default ExitInstance(). Even with no daorecordsets being opened it
crashes. If I comment out the CDaoDatabase::Open and Close lines,
it does not crash. A non-thread version of a similar program works
fine with similar DAO structure, except that the database variables
are in the CDocument and the close is triggered by
CView::DestroyWindow().
The worker control functions are normal global functions (not
classes), inside the app source file for convenience.
David O. Ohlssen
I _____________________________________ I
I | Davido@Commerce.CTech.ac.ZA | I
I | __ ____________ | I
I | / \/ Cape Town \ _ | I
I |__/ South Africa \/ \__________| I
I_________________________________________I
MCVICAR DAVID ugrad -- com50008@paisley.ac.uk
Thursday, May 16, 1996
[Mini-digest: 2 responses]
David Ohlssen wrote:
>
> NT 4.0.1234 VC++4.0
>
> I have tried using the CDaoDatabase class on the stack and heap and
> in the app. I have tried a 5 second sleep before calling the
> default ExitInstance(). Even with no daorecordsets being opened it
> crashes. If I comment out the CDaoDatabase::Open and Close lines,
> it does not crash. A non-thread version of a similar program works
> fine with similar DAO structure, except that the database variables
> are in the CDocument and the close is triggered by
> CView::DestroyWindow().
I experienced similar problems when doing something similar in a console
based Win32 based server. I traced through the MFC code and found that
unless there was a CWinApp available that there was an exception. This
was due to DAO trying to call the App to get a pointer to a function to
shutdown the Jet engine. By adding an unused CWinApp class I solved
this. It is possible that with the multiple threads accessing DAO that
once one of the threads is killed that it shuts down the Jet database
engine, when you then try to access it again you would get the exception
you talk of. This is only a suggestion and mayt be wrong but this
definitely happened in a console based app. Possibly this is one for
the FAQ ?
--
David A. McVicar
EMail: dmcvicar@bcs.org.uk / com50008@paisley.ac.uk
Phone - Home : 01505 322099 - Anytime before 22:00
Mobile: 0973 386463 - Anytime
-----From: Dan Kirby
Hi,
DAO can only be used in the primary thread of an application. This
information comes straight from the DAO developers. You must remember that
DAO is a technology which comes from the VB/Access products which support
applications with a single primary thread. That is the only way by which
DAO has been tested.
Some folks have been able to get things to work if they use the dbDAO C++
classes from the DAO SDK and don't intialize OLE in any other thread except
the thread which uses DAO but, again, it really was never tested with that
in mind.
The DAO team is looking at making DAO at least apartment model in the
future but there have been no timeframes announced for this. One key
problem is that DAO uses the Jet engine and that is not thread-safe so the
DAO group probably won't do much until the underlying db engine changes to
allow thread safety.
The MFC problem you are seeing is because MFC performs a DAO call from the
primary thread to Release the DBEngine object but the object was created in
a different thread. To do this, an OLE object must follow OLE apartment
threading rules which DAO does not.
--dan
Brian Jones -- BrianJ@ats-nt.apptechsys.com
Monday, May 20, 1996
Is CDatabase an effective workaround for this problem?
----------
From: owner-mfc-l[SMTP:owner-mfc-l@netcom.com]
Sent: Thursday, May 16, 1996 5:44 PM
To: mfc-l
Subject: Re: DAO "multithread" - interesting problem
[Mini-digest: 2 responses]
David Ohlssen wrote:
>
> NT 4.0.1234 VC++4.0
>
> I have tried using the CDaoDatabase class on the stack and heap and
> in the app. I have tried a 5 second sleep before calling the
> default ExitInstance(). Even with no daorecordsets being opened it
> crashes. If I comment out the CDaoDatabase::Open and Close lines,
> it does not crash. A non-thread version of a similar program works
> fine with similar DAO structure, except that the database variables
> are in the CDocument and the close is triggered by
> CView::DestroyWindow().
I experienced similar problems when doing something similar in a console
based Win32 based server. I traced through the MFC code and found that
unless there was a CWinApp available that there was an exception. This
was due to DAO trying to call the App to get a pointer to a function to
shutdown the Jet engine. By adding an unused CWinApp class I solved
this. It is possible that with the multiple threads accessing DAO that
once one of the threads is killed that it shuts down the Jet database
engine, when you then try to access it again you would get the exception
you talk of. This is only a suggestion and mayt be wrong but this
definitely happened in a console based app. Possibly this is one for
the FAQ ?
--
David A. McVicar
EMail: dmcvicar@bcs.org.uk / com50008@paisley.ac.uk
Phone - Home : 01505 322099 - Anytime before 22:00
Mobile: 0973 386463 - Anytime
-----From: Dan Kirby
Hi,
DAO can only be used in the primary thread of an application. This
information comes straight from the DAO developers. You must remember
that
DAO is a technology which comes from the VB/Access products which support
applications with a single primary thread. That is the only way by which
DAO has been tested.
Some folks have been able to get things to work if they use the dbDAO C++
classes from the DAO SDK and don't intialize OLE in any other thread
except
the thread which uses DAO but, again, it really was never tested with
that
in mind.
The DAO team is looking at making DAO at least apartment model in the
future but there have been no timeframes announced for this. One key
problem is that DAO uses the Jet engine and that is not thread-safe so
the
DAO group probably won't do much until the underlying db engine changes
to
allow thread safety.
The MFC problem you are seeing is because MFC performs a DAO call from
the
primary thread to Release the DBEngine object but the object was created
in
a different thread. To do this, an OLE object must follow OLE apartment
threading rules which DAO does not.
--dan
| Вернуться в корень Архива
|