diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 14956b243d..62b176697c 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,28 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-10-06 02:18 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/tests/speedtst.prg + * marked T054 as memory tests + + * harbour/source/vm/hvm.c + * harbour/source/vm/thread.c + * added hb_threadOnce( @ [, ] ) -> + This function allow to execute some code only once. It's usefull in + MT environment for initialization. + is variable which holds the execution status and have + to be initialized to NIL. In most of cases it will be simple static + variable in user code. + is optional codeblock which is executed only once (on 1-st + call with given ) + + * harbour/source/rtl/filesys.c + ! do not make any file name conversions in hb_fsNameConv() if HVM stack + is not allocated + + * harbour/source/rtl/gtcrs/gtcrs.c + * casting + 2008-10-06 01:06 UTC+0200 Viktor Szakats (harbour.01 syenar hu) * source/debug/debugger.prg * source/rtl/typefile.prg diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index 381060bfa2..ab8d5a91c9 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -3083,6 +3083,13 @@ HB_EXPORT BYTE * hb_fsNameConv( BYTE * szFileName, BOOL * pfFree ) TRIMFILENAME - strip trailing and leading spaces (also from extension) */ + if( !hb_stackId() ) + { + if( pfFree ) + *pfFree = FALSE; + return szFileName; + } + fTrim = hb_setGetTrimFileName(); cDirSep = hb_setGetDirSeparator(); iFileCase = hb_setGetFileCase(); diff --git a/harbour/source/rtl/gtcrs/gtcrs.c b/harbour/source/rtl/gtcrs/gtcrs.c index ed3634e3e1..ccf40e6278 100644 --- a/harbour/source/rtl/gtcrs/gtcrs.c +++ b/harbour/source/rtl/gtcrs/gtcrs.c @@ -1412,7 +1412,7 @@ static char *tiGetS( const char *capname ) { char *ptr; - ptr = tigetstr( capname ); + ptr = tigetstr( ( char * ) capname ); if ( ptr ) { if ( ptr == ( char * ) -1 ) diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 350221dae2..70d0c9f0f5 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -1031,10 +1031,10 @@ HB_EXPORT int hb_vmQuit( void ) hb_cdpReleaseAll(); /* releases codepages */ #endif hb_itemClear( hb_stackReturnItem() ); - hb_gcCollectAll( TRUE ); #if defined( HB_MT_VM ) + hb_threadExit(); hb_vmStackRelease(); /* release HVM stack and remove it from linked HVM stacks list */ #else hb_setRelease( hb_stackSetStruct() ); /* releases Sets */ diff --git a/harbour/source/vm/thread.c b/harbour/source/vm/thread.c index e86cf58a5d..c30dc14fe6 100644 --- a/harbour/source/vm/thread.c +++ b/harbour/source/vm/thread.c @@ -74,6 +74,7 @@ #endif static volatile BOOL s_fThreadInit = FALSE; +static PHB_ITEM s_pOnceMutex = NULL; #if !defined( HB_MT_VM ) /* nothing */ @@ -100,6 +101,8 @@ static volatile BOOL s_fThreadInit = FALSE; # if defined( HB_CRITICAL_INIT ) static HB_RAWCRITICAL_T s_critical_init; + static HB_RAWCRITICAL_T s_critical_once; + static HB_RAWCRITICAL_T s_critical_mtx; static void hb_threadCriticalInit( HB_CRITICAL_T * critical ) { if( !s_fThreadInit ) @@ -114,10 +117,12 @@ static volatile BOOL s_fThreadInit = FALSE; HB_CRITICAL_UNLOCK( s_critical_init ); } # else - static HB_CRITICAL_NEW( s_critical_init ); + static HB_CRITICAL_NEW( s_critical_once ); + static HB_CRITICAL_NEW( s_critical_mtx ); # endif # if defined( HB_COND_INIT ) + static HB_CRITICAL_NEW( s_critical_init ); static void hb_threadCondInit( HB_COND_T * cond ) { if( !s_fThreadInit ) @@ -147,6 +152,8 @@ void hb_threadInit( void ) /* nothing to do */ #elif defined( HB_CRITICAL_INIT ) HB_CRITICAL_INIT( s_critical_init ); + HB_CRITICAL_INIT( s_critical_once ); + HB_CRITICAL_INIT( s_critical_mtx ); #endif s_fThreadInit = TRUE; } @@ -157,10 +164,17 @@ void hb_threadExit( void ) if( s_fThreadInit ) { s_fThreadInit = FALSE; + if( s_pOnceMutex ) + { + hb_itemRelease( s_pOnceMutex ); + s_pOnceMutex = NULL; + } #if !defined( HB_MT_VM ) /* nothing to do */ #elif defined( HB_CRITICAL_DESTROY ) HB_CRITICAL_DESTROY( s_critical_init ); + HB_CRITICAL_DESTROY( s_critical_once ); + HB_CRITICAL_DESTROY( s_critical_mtx ); #endif } } @@ -761,6 +775,50 @@ HB_FUNC( HB_THREADTERMINATEALL ) #endif } +HB_FUNC( HB_THREADONCE ) +{ + PHB_ITEM pItem = hb_param( 1, HB_IT_ANY ); + if( pItem && ISBYREF( 1 ) ) + { + BOOL fFirstCall = FALSE; + if( HB_IS_NIL( pItem ) ) + { + PHB_ITEM pAction = hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ); + +#if defined( HB_MT_VM ) + if( !s_pOnceMutex ) + { + if( !s_fThreadInit ) + hb_threadInit(); + HB_CRITICAL_LOCK( s_critical_once ); + if( !s_pOnceMutex ) + s_pOnceMutex = hb_threadMutexCreate( FALSE ); + HB_CRITICAL_UNLOCK( s_critical_once ); + } + if( hb_threadMutexLock( s_pOnceMutex ) ) + { + if( HB_IS_NIL( pItem ) ) + { + hb_storl( TRUE, 1 ); + fFirstCall = TRUE; + if( pAction ) + hb_vmEvalBlock( pAction ); + } + hb_threadMutexUnlock( s_pOnceMutex ); + } +#else + hb_storl( TRUE, 1 ); + fFirstCall = TRUE; + if( pAction ) + hb_vmEvalBlock( pAction ); +#endif + } + hb_retl( fFirstCall ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + /* II. MUTEXES */ typedef struct _HB_MUTEX @@ -819,7 +877,7 @@ static void hb_mutexUnlink( PHB_MUTEX *pList, PHB_MUTEX pItem ) #if defined( HB_MT_VM ) static void hb_mutexUnlockList( PHB_MUTEX * pList, PHB_MTXLST * pStore ) { - HB_CRITICAL_LOCK( s_critical_init ); + HB_CRITICAL_LOCK( s_critical_mtx ); if( *pList ) { PHB_MUTEX pMutex = *pList; @@ -848,7 +906,7 @@ static void hb_mutexUnlockList( PHB_MUTEX * pList, PHB_MTXLST * pStore ) } while( pMutex != *pList ); } - HB_CRITICAL_UNLOCK( s_critical_init ); + HB_CRITICAL_UNLOCK( s_critical_mtx ); } static void hb_mutexLockList( PHB_MTXLST pList ) @@ -894,9 +952,9 @@ static HB_GARBAGE_FUNC( hb_mutexDestructor ) PHB_MUTEX pMutex = ( PHB_MUTEX ) Cargo; #if defined( HB_MT_VM ) - HB_CRITICAL_LOCK( s_critical_init ); + HB_CRITICAL_LOCK( s_critical_mtx ); hb_mutexUnlink( pMutex->fSync ? &s_pSyncList : &s_pMutexList, pMutex ); - HB_CRITICAL_UNLOCK( s_critical_init ); + HB_CRITICAL_UNLOCK( s_critical_mtx ); #else hb_mutexUnlink( pMutex->fSync ? &s_pSyncList : &s_pMutexList, pMutex ); #endif @@ -953,9 +1011,9 @@ PHB_ITEM hb_threadMutexCreate( BOOL fSync ) pMutex->fSync = fSync; #if defined( HB_MT_VM ) - HB_CRITICAL_LOCK( s_critical_init ); + HB_CRITICAL_LOCK( s_critical_mtx ); hb_mutexLink( fSync ? &s_pSyncList : &s_pMutexList, pMutex ); - HB_CRITICAL_UNLOCK( s_critical_init ); + HB_CRITICAL_UNLOCK( s_critical_mtx ); #else hb_mutexLink( fSync ? &s_pSyncList : &s_pMutexList, pMutex ); #endif diff --git a/harbour/tests/speedtst.prg b/harbour/tests/speedtst.prg index 6decb5e12c..b711bdcab9 100644 --- a/harbour/tests/speedtst.prg +++ b/harbour/tests/speedtst.prg @@ -55,10 +55,11 @@ proc main( ... ) - local aParams, nMT, cExclude, lScale, cParam, lSyntax, i + local aParams, nMT, cExclude, lScale, cParam, cMemTests, lSyntax, i aParams := hb_aparams() lSyntax := lScale := .f. + cMemTests := "029 030 023 025 027 040 041 043 052 053 019 022 031 032 054 " cExclude := "" nMT := 0 for each cParam in aParams @@ -79,13 +80,16 @@ proc main( ... ) endif elseif cParam = "--exclude=" if substr( cParam, 11 ) == "mem" - cExclude += "029 030 023 025 027 040 041 043 052 053 019 022 031 032 " + cExclude += cMemTests else cExclude += strtran( strtran( strtran( substr( cParam, 11 ), ; ".", " " ), ".", " " ), "/", " " ) + " " endif elseif cParam = "--only=" cExclude := "" + if substr( cParam, 8 ) == "mem" + cParam := cMemTests + endif for i := 1 to N_TESTS if !strzero( i, 3 ) $ cParam cExclude += strzero( i, 3 ) + " " @@ -214,6 +218,30 @@ return #endif +/* initialize mutex in hb_trheadDoOnce() */ +init proc once_init() + hb_threadOnce() +return + +function hb_threadOnce( xOnceControl, bAction ) + static s_mutex + local lFirstCall := .f. + if s_mutex == NIL + s_mutex := hb_mutexCreate() + endif + if xOnceControl == NIL + hb_mutexLock( s_mutex ) + if xOnceControl == NIL + xOnceControl := .t. + lFirstCall := .t. + if bAction != NIL + eval( bAction ) + endif + endif + hb_mutexUnlock( s_mutex ) + endif +return lFirstCall + #endif @@ -389,30 +417,6 @@ TEST t053 CODE x := f5() TEST t054 WITH c := dtos( date() ) CODE f_prv( c ) -/* initialize mutex in hb_trheadDoOnce() */ -init proc once_init() - hb_threadOnce() -return - -function hb_threadOnce( xOnceControl, bAction ) - static s_mutex - local lFirstCall := .f. - if s_mutex == NIL - s_mutex := hb_mutexCreate() - endif - if xOnceControl == NIL - hb_mutexLock( s_mutex ) - if xOnceControl == NIL - xOnceControl := .t. - lFirstCall := .t. - if bAction != NIL - eval( bAction ) - endif - endif - hb_mutexUnlock( s_mutex ) - endif -return lFirstCall - function thTest( mtxJobs, aResults ) local xJob while .T.