From 5964eac44cab3c2e0f34d0aa5e0c007446336a95 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Fri, 10 Oct 2008 20:46:50 +0000 Subject: [PATCH] 2008-10-10 22:46 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/vm/hvm.c * reduced the mutex lock time in thread exit state * harbour/source/vm/thread.c ; added note about possible behavior of hb_threadSelf() function in one very specific situation. It's documented and expected behavior * harbour/source/rtl/hbgtcore.c + added support for retrieving current HB_GTI_NOTIFIERBLOCK code block + added support for removing HB_GTI_NOTIFIERBLOCK code block without setting the new one --- harbour/ChangeLog | 14 +++++++++++ harbour/source/rtl/hbgtcore.c | 18 +++++++++++--- harbour/source/vm/hvm.c | 47 ++++++++++++++++++++++------------- harbour/source/vm/thread.c | 6 +++++ 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9ead5c1513..e8791fff72 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,20 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-10-10 22:46 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/vm/hvm.c + * reduced the mutex lock time in thread exit state + + * harbour/source/vm/thread.c + ; added note about possible behavior of hb_threadSelf() function + in one very specific situation. It's documented and expected + behavior + + * harbour/source/rtl/hbgtcore.c + + added support for retrieving current HB_GTI_NOTIFIERBLOCK code block + + added support for removing HB_GTI_NOTIFIERBLOCK code block without + setting the new one + 2008-10-10 21:22 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/vm/garbage.c * unblock HVM before executing destructors and releasing blocks diff --git a/harbour/source/rtl/hbgtcore.c b/harbour/source/rtl/hbgtcore.c index b549c27683..5629d53dc2 100644 --- a/harbour/source/rtl/hbgtcore.c +++ b/harbour/source/rtl/hbgtcore.c @@ -1571,11 +1571,21 @@ static BOOL hb_gt_def_Info( PHB_GT pGT, int iType, PHB_GT_INFO pInfo ) case HB_GTI_NOTIFIERBLOCK: if( pGT->pNotifierBlock ) { - hb_itemRelease( pGT->pNotifierBlock ); - pGT->pNotifierBlock = NULL; + if( pInfo->pResult ) + hb_itemCopy( pInfo->pResult, pGT->pNotifierBlock ); + else + pInfo->pResult = hb_itemNew( pGT->pNotifierBlock ); + } + if( pInfo->pNewVal ) + { + if( pGT->pNotifierBlock ) + { + hb_itemRelease( pGT->pNotifierBlock ); + pGT->pNotifierBlock = NULL; + } + if( hb_itemType( pInfo->pNewVal ) & HB_IT_BLOCK ) + pGT->pNotifierBlock = hb_itemNew( pInfo->pNewVal ); } - if( hb_itemType( pInfo->pNewVal ) & HB_IT_BLOCK ) - pGT->pNotifierBlock = hb_itemNew( pInfo->pNewVal ); break; default: diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index dfacf65abe..09451b3a05 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -614,8 +614,10 @@ static void hb_vmStackAdd( PHB_THREADSTATE pState ) pState->th_no = ++s_threadNo; } -static void hb_vmStackDel( PHB_THREADSTATE pState ) +static PHB_ITEM hb_vmStackDel( PHB_THREADSTATE pState ) { + PHB_ITEM pThItm; + HB_TRACE(HB_TR_DEBUG, ("hb_vmStackDel(%p)", pState)); pState->fActive = FALSE; @@ -633,19 +635,16 @@ static void hb_vmStackDel( PHB_THREADSTATE pState ) s_vmStackLst = NULL; } pState->pPrev = pState->pNext = NULL; - s_iStackCount--; } - if( pState->pThItm ) - { - PHB_ITEM pThItm = pState->pThItm; - pState->pThItm = NULL; - /* NOTE: releasing pThItm may force pState freeing if parent - * thread does not keep thread pointer item. So it's - * important to not access it later. [druzus] - */ - hb_itemRelease( pThItm ); - } + /* NOTE: releasing pThItm may force pState freeing if parent + * thread does not keep thread pointer item. So it's + * important to not access it later. [druzus] + */ + pThItm = pState->pThItm; + pState->pThItm = NULL; + + return pThItm; } static void hb_vmStackInit( PHB_THREADSTATE pState ) @@ -673,25 +672,32 @@ static void hb_vmStackRelease( void ) { HB_STACK_TLS_PRELOAD BOOL fLocked; + PHB_ITEM pThItm; HB_TRACE(HB_TR_DEBUG, ("hb_vmStackRelease()")); HB_VM_LOCK fLocked = hb_stackUnlock() == 1; + pThItm = hb_vmStackDel( ( PHB_THREADSTATE ) hb_stackList() ); - hb_vmStackDel( ( PHB_THREADSTATE ) hb_stackList() ); + HB_VM_UNLOCK + + if( pThItm ) + hb_itemRelease( pThItm ); hb_setRelease( hb_stackSetStruct() ); hb_stackFree(); hb_threadMutexUnlockAll(); + HB_VM_LOCK + if( fLocked ) - { s_iRunningCount--; - hb_threadCondBroadcast( &s_vmCond ); - } + + s_iStackCount--; + hb_threadCondBroadcast( &s_vmCond ); HB_VM_UNLOCK } @@ -711,13 +717,20 @@ HB_EXPORT BOOL hb_vmThreadRegister( void * Cargo ) HB_EXPORT void hb_vmThreadRelease( void * Cargo ) { + PHB_ITEM pThItm; + HB_TRACE(HB_TR_DEBUG, ("hb_vmThreadRelease(%p)", Cargo)); HB_VM_LOCK - hb_vmStackDel( ( PHB_THREADSTATE ) Cargo ); + pThItm = hb_vmStackDel( ( PHB_THREADSTATE ) Cargo ); + s_iStackCount--; + hb_threadCondBroadcast( &s_vmCond ); HB_VM_UNLOCK + + if( pThItm ) + hb_itemRelease( pThItm ); } /* thread entry point */ diff --git a/harbour/source/vm/thread.c b/harbour/source/vm/thread.c index a470914c0a..2b4e31115a 100644 --- a/harbour/source/vm/thread.c +++ b/harbour/source/vm/thread.c @@ -726,6 +726,12 @@ HB_FUNC( HB_THREADSELF ) { #if defined( HB_MT_VM ) PHB_THREADSTATE pThread = ( PHB_THREADSTATE ) hb_vmThreadState(); + /* It's possible that pThread will be NULL and this function will + * return NIL. It may happen only in one case when this function is + * executed by one of destructors of items stored in thread pointer + * item (in practice it can be only thread return value) and parent + * thread destroyed this thread pointer item. [druzus] + */ if( pThread ) hb_itemReturn( pThread->pThItm ); #endif