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( @<onceControl> [, <bAction> ] ) -> <lFirstCall>
      This function allow to execute some code only once. It's usefull in
      MT environment for initialization.
      <onceControl> 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.
      <bAction> is optional codeblock which is executed only once (on 1-st
      call with given <onceControl>)

  * 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
This commit is contained in:
Przemyslaw Czerpak
2008-10-06 00:19:10 +00:00
parent 809fd031dc
commit 423391977e
6 changed files with 126 additions and 35 deletions

View File

@@ -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( @<onceControl> [, <bAction> ] ) -> <lFirstCall>
This function allow to execute some code only once. It's usefull in
MT environment for initialization.
<onceControl> 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.
<bAction> is optional codeblock which is executed only once (on 1-st
call with given <onceControl>)
* 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

View File

@@ -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();

View File

@@ -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 )

View File

@@ -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 */

View File

@@ -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

View File

@@ -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.