Author | Topic: Multithreading causing DAC errors | |
---|---|---|
Martin Imber | Multithreading causing DAC errors on Wed, 05 Sep 2012 12:46:17 +0100 Hello I am modifying a 9 year old Xbase++ program to run multithreaded, I need to do some background data access while the main application is running. When closing the executable I get the following error. Program is normally VERY stable and is in 182 Error BASE/5 Description : Internal data structures corrupted Operation : dacCloseAll Thread ID : 1 Called from DACDATASOURCE:DESTROY(161) Called from DACSESSION:DISCONNECT(421) Called from EXIT: GT3SHUTDOWN(103) and so on through to where close was called. ****************************************** EXIT PROCEDURE GT3ShutDown DBCLOSEALL() oSession:disconnect() <------ line 103 RETURN ****************************************** this is the session creator ****************************************** FUNCTION ADSSetup ( cPath ) LOCAL oSession, aFields SET DEFAULT TO ( cPath ) IF LEFT(cPath,2) == 'C:' DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",1) ELSE DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",2) ENDIF IF LEFT(cPath,2) == '\\' oSession := dacSession():New( "ADSDBE", LEFT(cPath,LEN(cPath)-1) ) ELSE oSession := dacSession():New( "ADSDBE", LEFT(cPath,2) ) ENDIF IF ( oSession:isConnected( ) ) DbeInfo( COMPONENT_DATA, ADSDBE_TBL_MODE, ADSDBE_CDX) DbeInfo( COMPONENT_ORDER, ADSDBE_INDEX_EXT, "CDX") ELSE Hit_Key('>>ADS Error '+STR(oSession:getLastError())) ? "Error:", oSession:getLastError() MsgBox('no') ENDIF RETURN oSession ****************************************** this is my thread code ****************************************** CLASS DelMonitor FROM THREAD PROTECTED METHOD atStart, execute, atEnd VAR aAlias ENDCLASS METHOD DelMonitor:atStart ::aAlias := Array(154) ::aAlias[ 11] := Open_DB( 11,'TBarList', .T.) .... ::aAlias[154] := Open_DB(154,'TProdGrp', .T.) RETURN Self METHOD DelMonitor:atEnd hit_key('closing') Close_DB(::aAlias) RETURN Self METHOD DelMonitor:execute Check the arrays for batches to check hit_key('main bit of thread') RETURN Self Open_DB is my open DBF code and Close_DB closes all open aliases in ::aAlias Alias names are all prefixed with T to differenciate from the main servers. Any ideas please? Thanks Martin | |
James Loughner | Re: Multithreading causing DAC errors on Wed, 05 Sep 2012 10:45:24 -0400 1) kill the thread before quitting ie be sure you sever the connection before you kill the program 2) put a short sleep after the close_db Just guesses Jim On 09/05/2012 07:46 AM, Martin Imber wrote: > Hello > > I am modifying a 9 year old Xbase++ program to run multithreaded, I need > to do some background data access while the main application is running. > When closing the executable I get the following error. Program is > normally VERY stable and is in 182 > > Error BASE/5 > Description : Internal data structures corrupted > Operation : dacCloseAll > Thread ID : 1 > Called from DACDATASOURCE:DESTROY(161) > Called from DACSESSION:DISCONNECT(421) > Called from EXIT: GT3SHUTDOWN(103) > and so on through to where close was called. > > ****************************************** > EXIT PROCEDURE GT3ShutDown > > DBCLOSEALL() > oSession:disconnect() <------ line 103 > > RETURN > ****************************************** > this is the session creator > > ****************************************** > FUNCTION ADSSetup ( cPath ) > > LOCAL oSession, aFields > > SET DEFAULT TO ( cPath ) > > IF LEFT(cPath,2) == 'C:' > DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",1) > ELSE > DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",2) > ENDIF > > IF LEFT(cPath,2) == '\\' > oSession := dacSession():New( "ADSDBE", LEFT(cPath,LEN(cPath)-1) ) > ELSE > oSession := dacSession():New( "ADSDBE", LEFT(cPath,2) ) > ENDIF > > IF ( oSession:isConnected( ) ) > DbeInfo( COMPONENT_DATA, ADSDBE_TBL_MODE, ADSDBE_CDX) > DbeInfo( COMPONENT_ORDER, ADSDBE_INDEX_EXT, "CDX") > > ELSE > Hit_Key('>>ADS Error '+STR(oSession:getLastError())) > ? "Error:", oSession:getLastError() > MsgBox('no') > ENDIF > > RETURN oSession > ****************************************** > > > > this is my thread code > ****************************************** > CLASS DelMonitor FROM THREAD > > PROTECTED > METHOD atStart, execute, atEnd > > VAR aAlias > > ENDCLASS > METHOD DelMonitor:atStart > > ::aAlias := Array(154) > > ::aAlias[ 11] := Open_DB( 11,'TBarList', .T.) > .... > ::aAlias[154] := Open_DB(154,'TProdGrp', .T.) > > RETURN Self > METHOD DelMonitor:atEnd > hit_key('closing') > Close_DB(::aAlias) > RETURN Self > METHOD DelMonitor:execute > > Check the arrays for batches to check > > hit_key('main bit of thread') > > > RETURN Self > > > Open_DB is my open DBF code and Close_DB closes all open aliases in > ::aAlias Alias names are all prefixed with T to differenciate from the > main servers. > > Any ideas please? > > Thanks > > Martin | |
Martin Imber | Re: Multithreading causing DAC errors on Thu, 06 Sep 2012 09:44:05 +0100 Did the fix last night - rebuilt in 1.9 now it appears fine On 05/09/2012 15:45, James Loughner wrote: > 1) kill the thread before quitting ie be sure you sever the connection > before you kill the program > 2) put a short sleep after the close_db > > > Just guesses > > Jim > > On 09/05/2012 07:46 AM, Martin Imber wrote: >> Hello >> >> I am modifying a 9 year old Xbase++ program to run multithreaded, I need >> to do some background data access while the main application is running. >> When closing the executable I get the following error. Program is >> normally VERY stable and is in 182 >> >> Error BASE/5 >> Description : Internal data structures corrupted >> Operation : dacCloseAll >> Thread ID : 1 >> Called from DACDATASOURCE:DESTROY(161) >> Called from DACSESSION:DISCONNECT(421) >> Called from EXIT: GT3SHUTDOWN(103) >> and so on through to where close was called. >> >> ****************************************** >> EXIT PROCEDURE GT3ShutDown >> >> DBCLOSEALL() >> oSession:disconnect() <------ line 103 >> >> RETURN >> ****************************************** >> this is the session creator >> >> ****************************************** >> FUNCTION ADSSetup ( cPath ) >> >> LOCAL oSession, aFields >> >> SET DEFAULT TO ( cPath ) >> >> IF LEFT(cPath,2) == 'C:' >> DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",1) >> ELSE >> DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",2) >> ENDIF >> >> IF LEFT(cPath,2) == '\\' >> oSession := dacSession():New( "ADSDBE", LEFT(cPath,LEN(cPath)-1) ) >> ELSE >> oSession := dacSession():New( "ADSDBE", LEFT(cPath,2) ) >> ENDIF >> >> IF ( oSession:isConnected( ) ) >> DbeInfo( COMPONENT_DATA, ADSDBE_TBL_MODE, ADSDBE_CDX) >> DbeInfo( COMPONENT_ORDER, ADSDBE_INDEX_EXT, "CDX") >> >> ELSE >> Hit_Key('>>ADS Error '+STR(oSession:getLastError())) >> ? "Error:", oSession:getLastError() >> MsgBox('no') >> ENDIF >> >> RETURN oSession >> ****************************************** >> >> >> >> this is my thread code >> ****************************************** >> CLASS DelMonitor FROM THREAD >> >> PROTECTED >> METHOD atStart, execute, atEnd >> >> VAR aAlias >> >> ENDCLASS >> METHOD DelMonitor:atStart >> >> ::aAlias := Array(154) >> >> ::aAlias[ 11] := Open_DB( 11,'TBarList', .T.) >> .... >> ::aAlias[154] := Open_DB(154,'TProdGrp', .T.) >> >> RETURN Self >> METHOD DelMonitor:atEnd >> hit_key('closing') >> Close_DB(::aAlias) >> RETURN Self >> METHOD DelMonitor:execute >> >> Check the arrays for batches to check >> >> hit_key('main bit of thread') >> >> >> RETURN Self >> >> >> Open_DB is my open DBF code and Close_DB closes all open aliases in >> ::aAlias Alias names are all prefixed with T to differenciate from the >> main servers. >> >> Any ideas please? >> >> Thanks >> >> Martin > | |
Jorge L | Re: Multithreading causing DAC errors on Wed, 05 Sep 2012 11:52:24 -0300 Hi Martín, in an exit procedure first i test if the object is not destroyed by the normal exit of the program regards "Martin Imber" escribió en el mensaje de noticias:113e68fa$2cfd23dc$19084@news.alaska-software.com... Hello I am modifying a 9 year old Xbase++ program to run multithreaded, I need to do some background data access while the main application is running. When closing the executable I get the following error. Program is normally VERY stable and is in 182 Error BASE/5 Description : Internal data structures corrupted Operation : dacCloseAll Thread ID : 1 Called from DACDATASOURCE:DESTROY(161) Called from DACSESSION:DISCONNECT(421) Called from EXIT: GT3SHUTDOWN(103) and so on through to where close was called. ****************************************** EXIT PROCEDURE GT3ShutDown DBCLOSEALL() oSession:disconnect() <------ line 103 RETURN ****************************************** this is the session creator ****************************************** FUNCTION ADSSetup ( cPath ) LOCAL oSession, aFields SET DEFAULT TO ( cPath ) IF LEFT(cPath,2) == 'C:' DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",1) ELSE DllCall("ACE32.DLL",DLL_STDCALL,"AdsSetServerType",2) ENDIF IF LEFT(cPath,2) == '\\' oSession := dacSession():New( "ADSDBE", LEFT(cPath,LEN(cPath)-1) ) ELSE oSession := dacSession():New( "ADSDBE", LEFT(cPath,2) ) ENDIF IF ( oSession:isConnected( ) ) DbeInfo( COMPONENT_DATA, ADSDBE_TBL_MODE, ADSDBE_CDX) DbeInfo( COMPONENT_ORDER, ADSDBE_INDEX_EXT, "CDX") ELSE Hit_Key('>>ADS Error '+STR(oSession:getLastError())) ? "Error:", oSession:getLastError() MsgBox('no') ENDIF RETURN oSession ****************************************** this is my thread code ****************************************** CLASS DelMonitor FROM THREAD PROTECTED METHOD atStart, execute, atEnd VAR aAlias ENDCLASS METHOD DelMonitor:atStart ::aAlias := Array(154) ::aAlias[ 11] := Open_DB( 11,'TBarList', .T.) .... ::aAlias[154] := Open_DB(154,'TProdGrp', .T.) RETURN Self METHOD DelMonitor:atEnd hit_key('closing') Close_DB(::aAlias) RETURN Self METHOD DelMonitor:execute Check the arrays for batches to check hit_key('main bit of thread') RETURN Self Open_DB is my open DBF code and Close_DB closes all open aliases in ::aAlias Alias names are all prefixed with T to differenciate from the main servers. Any ideas please? Thanks Martin |