Ron: This same problem Maurilio describes occurs with the most current builds of xharbour builder and for this reason we can't test the Outlook add-in with any recent versions of xbuilder because Outlooks bombs upon closing it.
Regards, Maurilio Longo wrote: > I've received a message from Przemyslaw that I attach here, I think we should > seriously fix these problems, right now xharbour is not useable anymore, not > only in MT mode but even a plain ST code with a destructor (which does not > uses statics nor creates now objects inside destructor). > > Maurilio. > > > Message from Przemyslaw follows > --------8<----------------------------- > > It's causes by: > STATIC lInErr > inside rtl/terror.prg > > below I'm forwarding the last message I sent to Phil with a patch > which resolves the problem by simple removing lInErr. > Please note that there is s_iLaunchCount for protection against recursive > error calls inside source/vm/errorapi.c which in MT version is part of HVM > stack. > > The problem with destructors your reported is probably caused by > executing destructors also for statics variables. Because class > definition is stored inside such variables then it means that now > you cannot create any new object inside destructor even if you want > to remove it immediately. It also means that you should not expect > any valid values in static variables you will want to access from > destructors so you should probably not use them in destructors at all. > > best regards, > Przemek > > > ----- Forwarded message from Przemyslaw Czerpak <[email protected]> ----- > > From: Przemyslaw Czerpak <[email protected]> > Subject: Re: [xHarbour-developers] ChangeLog 2008-12-23 01:00 UTC+0300 > PhilKrylov <phil a t newstar.rinet.ru> > To: Phil Krylov <[email protected]> > Date: Wed, 24 Dec 2008 03:25:48 +0100 > Lines: 131 > > On Wed, 24 Dec 2008, Przemyslaw Czerpak wrote: > > Hi Phil, > > Finally I located the problem with reference counters and why > it was crashing in T004. Just simply in some syncing after CVS > update I had to add by mistake HB_ATOMIC_INC()/HB_ATOMIC_DEC() > macros definition to the section which is used for ST mode. > If you moved it then readonly access to complex variables > begins to work without crashes. Looking for the problem I also > found that hb_itemUnShareString() was copied from Harbour as > is without adopting it to xHarbour. I have serious doubts if > Miguel well knows what he is doing porting Harbour code only > partially. Someone should verify such modifications. > I'm attaching patch which resolves this problems and speedtst.prg > begins to work with xHarbour. But it was rather trivial things. > Now you should look for much more complicated ones. F.e. race > conditions when threads are started/finished which causes that > programs creating simultaneously many short life threads crashes, > memvar variables which causes unreported memory leaks so in practice > cannot be use in MT programs which have to be executed for long time > creating many threads (each new thread allocates new dynamic symbols > for each used memvar which is never released), add MT protection > for classy code, remove all global static variables like > hb_vm_bQuitRequest, s_iBaseLine, hb_vm_iTry, ... > check the .prg code which also uses many static variables > (probably you will have to add support for THREAD STATIC if > you will want to make some things like GETLIST working in MT > mode), make SETs thread local (or any code which have to use > them cannot be ported to MT), updated GT code and enable GT > locking (f.e. see gtapi.c in Harbour and xHarbour), clean > basic thread API to eliminate race conditions which xHarbour > thread functions have (see some notes in speedtst.prg), fix > some compiler constructions like multivalue macros (f.e.: > a[&("1,2")], qout(&("3,4")), a:={&("5,6,7"})] ) or TRY/CATCH > which are not MT safe, update debugger for MT mode, reduce > number of internal locks which kill scalability - you probably > noticed in speedtst results that on real multiCPU machine is > more efficient to execute simultaneously 2 * <numCPU> instances > of single thread xHarbour program then <numCPU> threads in MT one. > Here it will be necessary to strongly change some subsystems. > F.e. whole macro compiler is protected by MUTEX so only one thread > can access it. To resolve it it's necessary to rewrite compiler, > macrocompiler and lexer code to be MT and reentrant safe. > And probably many other things I do not remember know. If you > are interested then I can try to collect modifications I had > to made in Harbour when I was working on MT mode. I still should > have a list I created over year ago. > They should help you to locate places which should be updated. > HTH > > Marry Christmas and Happy New Year, > Przemek > > > * xharbour/config/rules.cf > * give PRG_USR higher priority then HB_FLAGS > > * xharbour/include/thread.h > ! fixed declaration of HB_ATOMIC_INC()/HB_ATOMIC_DEC() macros > for 32bit x86 *nixes - by mistake it was added to ST section > > * xharbour/source/rtl/terror.prg > ! removed lInErr static variable - it breaks using errorNew() in > MT programs > > * xharbour/source/vm/itemapi.c > ! fixed copied as is from Harbour hb_itemUnShareString() > Harbour uses different HVM internals and such code cannot > be copied without adopting to xHarbour > > * xharbour/tests/speedtst.prg > ! fixed possible race condition in initialization > + added SET WORKAREA PRIVATE > > Index: config/rules.cf > =================================================================== > RCS file: /cvsroot/xharbour/xharbour/config/rules.cf,v > retrieving revision 1.13 > diff -u -r1.13 rules.cf > --- config/rules.cf 16 Mar 2008 19:15:57 -0000 1.13 > +++ config/rules.cf 24 Dec 2008 02:19:44 -0000 > @@ -85,7 +85,7 @@ > else > # Rule to generate a C file from a PRG file. > %.c : $(GRANDP)%.prg > - $(HB) $? $(PRG_USR) $(HB_FLAGS) > + $(HB) $? $(HB_FLAGS) $(PRG_USR) > endif > > ifeq ($(SHLVL),) # COMMAND.COM > Index: include/thread.h > =================================================================== > RCS file: /cvsroot/xharbour/xharbour/include/thread.h,v > retrieving revision 1.126 > diff -u -r1.126 thread.h > --- include/thread.h 23 Dec 2008 18:06:33 -0000 1.126 > +++ include/thread.h 24 Dec 2008 02:19:44 -0000 > @@ -396,8 +396,37 @@ > > #endif > > - #define HB_ATOMIC_INC( x ) ( ++(x) ) > - #define HB_ATOMIC_DEC( x ) ( --(x) ) > + #if HB_COUNTER_SIZE == 4 && defined( __GNUC__ ) && 1 && \ > + ( defined( i386 ) || defined( __i386__ ) || defined( __x86_64__ ) ) > + > + static __inline__ void hb_atomic_inc32( volatile int * p ) > + { > + __asm__ __volatile__( > + "lock; incl %0\n" > + :"=m" (*p) :"m" (*p) > + ); > + } > + > + static __inline__ int hb_atomic_dec32( volatile int * p ) > + { > + unsigned char c; > + __asm__ __volatile__( > + "lock; decl %0\n" > + "sete %1\n" > + :"=m" (*p), "=qm" (c) :"m" (*p) : "memory" > + ); > + return c == 0; > + } > + > + #define HB_ATOMIC_INC( x ) ( hb_atomic_inc32( ( volatile int * ) > &(x) ) ) > + #define HB_ATOMIC_DEC( x ) ( hb_atomic_dec32( ( volatile int * ) > &(x) ) ) > + > + #else > + > + #define HB_ATOMIC_INC( x ) ( ++(x) ) > + #define HB_ATOMIC_DEC( x ) ( --(x) ) > + > + #endif > > #define HB_MUTEX_T HB_CRITICAL_T > #define HB_MUTEX_INIT( x ) HB_CRITICAL_INIT( x ) > @@ -875,37 +904,8 @@ > > #else > > - #if HB_COUNTER_SIZE == 4 && defined( __GNUC__ ) && \ > - ( defined( i386 ) || defined( __i386__ ) || defined( __x86_64__ ) ) > - > - static __inline__ void hb_atomic_inc32( volatile int * p ) > - { > - __asm__ __volatile__( > - "lock; incl %0\n" > - :"=m" (*p) :"m" (*p) > - ); > - } > - > - static __inline__ int hb_atomic_dec32( volatile int * p ) > - { > - unsigned char c; > - __asm__ __volatile__( > - "lock; decl %0\n" > - "sete %1\n" > - :"=m" (*p), "=qm" (c) :"m" (*p) : "memory" > - ); > - return c == 0; > - } > - > - #define HB_ATOMIC_INC( x ) ( hb_atomic_inc32( ( volatile int * ) > &(x) ) ) > - #define HB_ATOMIC_DEC( x ) ( hb_atomic_dec32( ( volatile int * ) > &(x) ) ) > - > - #else > - > - #define HB_ATOMIC_INC( x ) ( ++(x) ) > - #define HB_ATOMIC_DEC( x ) ( --(x) ) > - > - #endif > + #define HB_ATOMIC_INC( x ) ( ++(x) ) > + #define HB_ATOMIC_DEC( x ) ( --(x) ) > > #define HB_CRITICAL_LOCK( x ) > #define HB_CRITICAL_TRYLOCK( x ) > Index: source/rtl/terror.prg > =================================================================== > RCS file: /cvsroot/xharbour/xharbour/source/rtl/terror.prg,v > retrieving revision 1.19 > diff -u -r1.19 terror.prg > --- source/rtl/terror.prg 27 Jun 2008 06:21:49 -0000 1.19 > +++ source/rtl/terror.prg 24 Dec 2008 02:19:44 -0000 > @@ -61,19 +61,12 @@ > > FUNCTION ErrorNew( SubSystem, GenCode, SubCode, Operation, Description, Args, > ModuleName, ProcName, ProcLine ) > > - STATIC lInErr := .F., s_oClass > + STATIC s_oClass > LOCAL oErr > LOCAL nLevel, aaStack > > //TraceLog( SubSystem, GenCode, SubCode, Operation, Description, Args, > ModuleName, ProcName, ProcLine ) > > - // Avoid RECURSIVE Errors. > - IF lInErr > - RETURN NIL > - ELSE > - lInErr := .T. > - ENDIF > - > IF s_oClass == NIL > s_oClass := HBClass():New( "ERROR" ) > > @@ -160,8 +153,6 @@ > oErr:VMThreadId := ThreadGetCurrentInternal() > #endif > > - lInErr := .F. > - > RETURN oErr > > FUNCTION __eInstVar53( oVar, cMethod, xValue, cType, nSubCode, bValid ) > Index: source/vm/itemapi.c > =================================================================== > RCS file: /cvsroot/xharbour/xharbour/source/vm/itemapi.c,v > retrieving revision 1.155 > diff -u -r1.155 itemapi.c > --- source/vm/itemapi.c 3 Dec 2008 11:09:45 -0000 1.155 > +++ source/vm/itemapi.c 24 Dec 2008 02:19:44 -0000 > @@ -1521,14 +1521,19 @@ > HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemUnShareString(%p)", pItem)); > > if( pItem->item.asString.allocated == 0 || > - hb_xRefCount( pItem->item.asString.value ) > 1 ) > + *( pItem->item.asString.pulHolders ) > 1 ) > { > ULONG ulLen = pItem->item.asString.length + 1; > char *szText = ( char* ) hb_xgrab( ulLen ); > > hb_xmemcpy( szText, pItem->item.asString.value, ulLen ); > if( pItem->item.asString.allocated ) > - hb_xRefDec( pItem->item.asString.value ); > + { > + if( HB_ATOMIC_DEC( *( pItem->item.asString.pulHolders ) ) == 0 ) > + { > + hb_xfree( pItem->item.asString.value ); > + } > + } > pItem->item.asString.value = szText; > pItem->item.asString.allocated = ulLen; > } > Index: tests/speedtst.prg > =================================================================== > RCS file: /cvsroot/xharbour/xharbour/tests/speedtst.prg,v > retrieving revision 1.8 > diff -u -r1.8 speedtst.prg > --- tests/speedtst.prg 23 Dec 2008 18:06:33 -0000 1.8 > +++ tests/speedtst.prg 24 Dec 2008 02:19:45 -0000 > @@ -11,7 +11,6 @@ > * > */ > > - > #define N_TESTS 54 > #define N_LOOPS 1000000 > #define ARR_LEN 16 > @@ -241,7 +240,13 @@ > > /* initialize mutex in hb_trheadDoOnce() */ > init proc once_init() > + set workarea private > hb_threadOnce() > + /* initialize error object to reduce possible crashes when two > + * threads will try to create new error class simultaneously > + * xHarbour does not have any protection against such situation > + */ > + errorNew() > return > > function hb_threadOnce( xOnceControl, bAction ) > @@ -253,11 +258,11 @@ > if xOnceControl == NIL > hb_mutexLock( s_mutex ) > if xOnceControl == NIL > - xOnceControl := .t. > - lFirstCall := .t. > if bAction != NIL > eval( bAction ) > endif > + xOnceControl := .t. > + lFirstCall := .t. > endif > hb_mutexUnlock( s_mutex ) > endif > @@ -275,15 +280,15 @@ > TEST t003 WITH L_D:=date() CODE x := L_D > > TEST t004 INIT _( static s_once, S_C ) ; > - INIT iif( hb_threadOnce( @s_once ), S_C := dtos(date()), ) ; > + INIT hb_threadOnce( @s_once, {|| S_C := dtos( date() ) } ) ; > CODE x := S_C > > TEST t005 INIT _( static s_once, S_N ) ; > - INIT iif( hb_threadOnce( @s_once ), S_N := 112345.67, ) ; > + INIT hb_threadOnce( @s_once, {|| S_N := 112345.67 } ) ; > CODE x := S_N > > TEST t006 INIT _( static s_once, S_D ) ; > - INIT iif( hb_threadOnce( @s_once ), S_D := date(), ) ; > + INIT hb_threadOnce( @s_once, {|| S_D := date() } ) ; > CODE x := S_D > > TEST t007 INIT _( memvar M_C ) INIT _( private M_C := dtos( date() ) ) ; > @@ -298,19 +303,19 @@ > TEST t010 INIT _( memvar P_C ) ; > INIT _( static s_once ) ; > INIT _( public P_C ) ; > - INIT iif( hb_threadOnce( @s_once ), P_C := dtos( date() ), ) ; > + INIT hb_threadOnce( @s_once, {|| P_C := dtos( date() ) } ) ; > CODE x := P_C > > TEST t011 INIT _( memvar P_N ) ; > INIT _( static s_once ) ; > INIT _( public P_N ) ; > - INIT iif( hb_threadOnce( @s_once ), P_N := 112345.67, ) ; > + INIT hb_threadOnce( @s_once, {|| P_N := 112345.67 } ) ; > CODE x := P_N > > TEST t012 INIT _( memvar P_D ) ; > INIT _( static s_once ) ; > INIT _( public P_D ) ; > - INIT iif( hb_threadOnce( @s_once ), P_D := date(), ) ; > + INIT hb_threadOnce( @s_once, {|| P_D := date() } ) ; > CODE x := P_D > > TEST t013 INIT _( field F_C ) INIT use_dbsh() EXIT close_db() ; > > > ----- End forwarded message ----- > > -- Luis Krause Mantilla lkrausem at shaw dot ca luis_krause at hotmail dot com "May the Source be with GNU" ------------------------------------------------------------------------------ Check out the new SourceForge.net Marketplace. It is the best place to buy or sell services for just about anything Open Source. http://p.sf.net/sfu/Xq1LFB _______________________________________________ xHarbour-developers mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/xharbour-developers

