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

Reply via email to