Ron:

I can't create one since it occurs only with the add-in using xharbour 
builder.
I haven't seen that error with xharbour.org compiler since we don't use MT.

Ron Pinkas wrote:
> Maurilio, Luis,
>
> Please post a REDUCED, yet SELF CONTAINED, sample that shows the problem.
>
> Ron
>
> --------------------------------------------------
> From: "Luis Krause Mantilla" <lkrau...@shaw.ca>
> Sent: Thursday, January 08, 2009 9:27 AM
> To: "Maurilio Longo" <maurilio.lo...@libero.it>
> Cc: "Xharbour-Developers List" 
> <xharbour-developers@lists.sourceforge.net>; "Ron Pinkas" 
> <r...@xharbour.com>
> Subject: Re: [xHarbour-developers] MT build dies at startup
>
>> 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 <dru...@acn.waw.pl> 
>>> -----
>>>
>>> From: Przemyslaw Czerpak <dru...@acn.waw.pl>
>>> Subject: Re: [xHarbour-developers] ChangeLog 2008-12-23 01:00 UTC+0300
>>> PhilKrylov <phil a t newstar.rinet.ru>
>>> To: Phil Krylov <p...@newstar.rinet.ru>
>>> 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
>> xHarbour-developers@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/xharbour-developers
>>
>

-- 
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
xHarbour-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xharbour-developers

Reply via email to