Alaska Software Inc. - Multithreading causing DAC errors
Username: Password:
AuthorTopic: Multithreading causing DAC errors
Martin ImberMultithreading 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 LoughnerRe: 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 ImberRe: 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 LRe: 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