ChangeLog 2001-03-16 16:10 UTC+0100
This commit is contained in:
@@ -1,3 +1,29 @@
|
||||
2001-03-16 16:10 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
|
||||
|
||||
*doc/en/garbage.txt
|
||||
*include/hbapi.h
|
||||
*source/vm/garbage.c
|
||||
*source/vm/itemapi.c
|
||||
* new functions: hb_gcGripGet() and hb_gcGripDrop() for dynamic
|
||||
allocation/deallocation of items
|
||||
* added redefinition of _getGrip/_dropGrip to use
|
||||
hb_gcGripGet/hb_gcGripDrop
|
||||
* items allocated with hb_itemNew() or direct _getGrip() calls are
|
||||
maintained properly by the Garbage Collector - there is no need
|
||||
to locking/unlocking such items.
|
||||
* removed no longer needed hb_gcLockItem/hb_gcUnlockItem
|
||||
|
||||
*source/rdd/dbcmd.c
|
||||
*source/rdd/workarea.c
|
||||
*source/rdd/dbfntx/dbfntx1.c
|
||||
*source/rtl/errorapi.c
|
||||
*source/rtl/idle.c
|
||||
*source/rtl/setkey.c
|
||||
* removed no longer needed calls for hb_gcLockItem/hb_gcUnlockItem
|
||||
|
||||
NOTE: there is no hb_gcLockItem/hb_gcUnlockItem functions - please remove
|
||||
calls for these functions from your code.
|
||||
|
||||
2001-03-15 17:00 UTC-0500 David G. Holm <dholm@jsd-llc.com>
|
||||
|
||||
* contrib/libmisc/Makefile
|
||||
|
||||
@@ -29,24 +29,16 @@
|
||||
* and are stored in class shared variables.
|
||||
*
|
||||
* In special cases when the value of a harbour variable is stored internally
|
||||
* in some static area (at C or assembler level), for example SETKEY()
|
||||
* stores codeblocks that will be evaluated when a key is pressed,
|
||||
* the garbage collector will be not able to scan such values since it
|
||||
* doesn't know their location. This could cause some memory blocks to be
|
||||
* released prematurely. To prevent the premature deallocation of such memory
|
||||
* blocks they have to be locked for the garbage collector. The memory block
|
||||
* can be locked with hb_gcLockItem() (recommended method) if
|
||||
* harbour item structure is used or hb_gcLock() function if a direct memory
|
||||
* pointer is used. The memory block can be unlocked by hb_gcUnlockItem() or
|
||||
* hb_gcUnlock().
|
||||
* in some static area (at C or assembler level), the garbage collector will
|
||||
* be not able to scan such values since it doesn't know their location. This
|
||||
* could cause some memory blocks to be released prematurely. To prevent the
|
||||
* premature deallocation of such memory blocks the static data have to store
|
||||
* a pointer to the value created with hb_itemNew() function.
|
||||
* Example:
|
||||
* static HB_ITEM s_item; // this item can be released by the GC
|
||||
*
|
||||
* Notice however that all variables passed to a low level function are
|
||||
* passed via the eval stack, so they don't require locking during the
|
||||
* function call. The locking will be required if a passed value is copied
|
||||
* into some static area to make it available for other low-level functions
|
||||
* called after the exit from function that stored the value. This is required
|
||||
* because the value is removed from the eval stack after the function call and
|
||||
* it can be no longer be referenced by other variables.
|
||||
* static HB_ITEM_PTR pItem; // this item will be maintained correctly
|
||||
* pItem = hb_itemNew( hb_param(1, IT_BLOCK) );
|
||||
*
|
||||
* However, scanning of all variables can be a time consuming operation. It
|
||||
* requires that all allocated arrays have to be traversed through all their
|
||||
@@ -68,15 +60,6 @@
|
||||
* function calls. Memory allocated by hb_gcAlloc() should be released with
|
||||
* hb_gcFree() function.
|
||||
*
|
||||
* Locking memory </par>
|
||||
* --------------
|
||||
*
|
||||
* The memory allocated with hb_gcAlloc() should be locked to prevent
|
||||
* automatic releasing if such a memory pointer is not stored within a
|
||||
* harbour level variable. All harbour values (items) stored internally
|
||||
* in static C area have to be locked.
|
||||
* See hb_gcLockItem() and hb_gcUnlockItem() for more information.
|
||||
*
|
||||
* The garbage collecting </par>
|
||||
* ----------------------
|
||||
*
|
||||
@@ -110,7 +93,7 @@
|
||||
* See HB_GCALL() for explanation of how to call this function from your
|
||||
* harbour code.
|
||||
* $SEEALSO$
|
||||
* hb_gcAlloc(),hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem(),hb_gcCollectAll(),hb_gcItemRef(),HB_GCALL(),HB_IDLESTATE()
|
||||
* hb_gcAlloc(),hb_gcFree(),hb_gcCollectAll(),hb_gcItemRef(),HB_GCALL(),HB_IDLESTATE()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
@@ -157,7 +140,7 @@
|
||||
* $FILES$
|
||||
* source/vm/garbage.c
|
||||
* $SEEALSO$
|
||||
* hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem()
|
||||
* hb_gcFree()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
@@ -189,87 +172,7 @@
|
||||
* $FILES$
|
||||
* source/vm/garbage.c
|
||||
* $SEEALSO$
|
||||
* hb_gcAlloc(),hb_gcLockItem(),hb_gcUnlockItem()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
/* $DOC$
|
||||
* $FUNCNAME$
|
||||
* hb_gcLockItem()
|
||||
* $CATEGORY$
|
||||
* The garbage collector
|
||||
* $ONELINER$
|
||||
* Locks the memory to prevent deallocation by the garbage collector.
|
||||
* $SYNTAX$
|
||||
* void hb_gcLockItem( HB_ITEM_PTR pItem );
|
||||
* $ARGUMENTS$
|
||||
* <pItem> The pointer to item structure that will be locked. The
|
||||
* passed item can be of any datatype although arrays, objects
|
||||
* and codeblocks are locked only. Other datatypes don't require
|
||||
* locking so they are simply ignored.
|
||||
* $RETURNS$
|
||||
* Nothing.
|
||||
* $DESCRIPTION$
|
||||
* hb_gcLockItem() is used to lock the memory pointer stored in
|
||||
* the passed item structure. It suppres the memory releasing
|
||||
* if the garbage collector will not find any reference to this
|
||||
* pointer. The garbage collector is storing the lock counter -
|
||||
* every call of this function increases the counter. The item is
|
||||
* locked if this counter is greather then 0.
|
||||
* $EXAMPLES$
|
||||
* See source/rtl/setkey.c
|
||||
* $STATUS$
|
||||
* C
|
||||
* $COMPLIANCE$
|
||||
* This function is a Harbour extension
|
||||
* $PLATFORMS$
|
||||
* All
|
||||
* $FILES$
|
||||
* source/vm/garbage.c
|
||||
* $SEEALSO$
|
||||
* hb_gcAlloc(),hb_gcFree(),hb_gcUnlockItem()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
/* $DOC$
|
||||
* $FUNCNAME$
|
||||
* hb_gcUnlockItem()
|
||||
* $CATEGORY$
|
||||
* The garbage collector
|
||||
* $ONELINER$
|
||||
* Unlocks the memory to prevent deallocation by the garbage collector.
|
||||
* $SYNTAX$
|
||||
* void hb_gcUnlockItem( HB_ITEM_PTR pItem );
|
||||
* $ARGUMENTS$
|
||||
* <pItem> The pointer to item structure that will be unlocked. The
|
||||
* passed item can be of any datatype although arrays, objects
|
||||
* and codeblocks are unlocked only. Other datatypes don't require
|
||||
* locking so they are simply ignored.
|
||||
* $RETURNS$
|
||||
* Nothing.
|
||||
* $DESCRIPTION$
|
||||
* hb_gcUnlockItem() is used to unlock the memory pointer stored in
|
||||
* the passed item structure that was previously locked with
|
||||
* hb_gcLockItem() call. It allows to release the memory during
|
||||
* garbage collecting if the garbage collector will not find any
|
||||
* reference to this pointer. The garbage collector is storing the
|
||||
* lock counter - every call of this function decreases the counter.
|
||||
* This function doesn't deallocate memory stored inside the item -
|
||||
* the memory can be deallocated however during the closest garbage
|
||||
* collecting if the lock counter is equal to 0 and the memory pointer
|
||||
* is not referenced by any harbour level variable.
|
||||
* $EXAMPLES$
|
||||
* See source/rtl/setkey.c
|
||||
* $STATUS$
|
||||
* C
|
||||
* $COMPLIANCE$
|
||||
* This function is a Harbour extension
|
||||
* $PLATFORMS$
|
||||
* All
|
||||
* $FILES$
|
||||
* source/vm/garbage.c
|
||||
* $SEEALSO$
|
||||
* hb_gcAlloc(),hb_gcFree(),hb_gcLockItem()
|
||||
* hb_gcAlloc()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
@@ -300,7 +203,7 @@
|
||||
* $FILES$
|
||||
* source/vm/garbage.c
|
||||
* $SEEALSO$
|
||||
* hb_gcAlloc(),hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem()
|
||||
* hb_gcAlloc(),hb_gcFree()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
@@ -340,7 +243,7 @@
|
||||
* $FILES$
|
||||
* source/vm/garbage.c
|
||||
* $SEEALSO$
|
||||
* hb_gcAlloc(),hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem()
|
||||
* hb_gcAlloc(),hb_gcFree()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
|
||||
@@ -511,12 +511,15 @@ extern char * hb_macroGetType( HB_ITEM_PTR pItem ); /* determine the type of an
|
||||
typedef HB_GARBAGE_FUNC( HB_GARBAGE_FUNC_ );
|
||||
typedef HB_GARBAGE_FUNC_ *HB_GARBAGE_FUNC_PTR;
|
||||
|
||||
extern HB_ITEM_PTR hb_gcGripGet( HB_ITEM_PTR pItem );
|
||||
extern void hb_gcGripDrop( HB_ITEM_PTR pItem );
|
||||
#define _getGrip hb_gcGripGet
|
||||
#define _getDrop hb_gcGripDrop
|
||||
|
||||
extern void * hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pFunc ); /* allocates a memory controlled by the garbage collector */
|
||||
extern void hb_gcFree( void *pAlloc ); /* deallocates a memory allocated by the garbage collector */
|
||||
extern void * hb_gcLock( void *pAlloc ); /* do not release passed memory block */
|
||||
extern void * hb_gcUnlock( void *pAlloc ); /* passed block is allowed to be released */
|
||||
extern void hb_gcLockItem( HB_ITEM_PTR pItem ); /* do not release a memory block stored inside an item */
|
||||
extern void hb_gcUnlockItem( HB_ITEM_PTR pItem ); /* allow to release the item */
|
||||
extern void hb_gcCollect( void ); /* checks if a single memory block can be released */
|
||||
extern void hb_gcCollectAll( void ); /* checks if all memory blocks can be released */
|
||||
extern void hb_gcItemRef( HB_ITEM_PTR pItem ); /* checks if passed item refers passed memory block pointer */
|
||||
|
||||
@@ -2222,7 +2222,6 @@ HB_FUNC( ORDCONDSET )
|
||||
{
|
||||
lpdbOrdCondInfo->itmCobFor = hb_itemNew( NULL );
|
||||
hb_itemCopy( lpdbOrdCondInfo->itmCobFor, pItem );
|
||||
hb_gcLockItem( lpdbOrdCondInfo->itmCobFor );
|
||||
}
|
||||
else
|
||||
lpdbOrdCondInfo->itmCobFor = NULL;
|
||||
@@ -2236,7 +2235,6 @@ HB_FUNC( ORDCONDSET )
|
||||
{
|
||||
lpdbOrdCondInfo->itmCobWhile = hb_itemNew( NULL );
|
||||
hb_itemCopy( lpdbOrdCondInfo->itmCobWhile, pItem );
|
||||
hb_gcLockItem( lpdbOrdCondInfo->itmCobWhile );
|
||||
}
|
||||
else
|
||||
lpdbOrdCondInfo->itmCobWhile = NULL;
|
||||
@@ -2246,7 +2244,6 @@ HB_FUNC( ORDCONDSET )
|
||||
{
|
||||
lpdbOrdCondInfo->itmCobEval = hb_itemNew( NULL );
|
||||
hb_itemCopy( lpdbOrdCondInfo->itmCobEval, pItem );
|
||||
hb_gcLockItem( lpdbOrdCondInfo->itmCobEval );
|
||||
}
|
||||
else
|
||||
lpdbOrdCondInfo->itmCobEval = NULL;
|
||||
@@ -2834,7 +2831,6 @@ HB_FUNC( DBSETRELATION )
|
||||
|
||||
dbRelations.lpaChild = ( AREAP ) s_pArea->pArea;
|
||||
dbRelations.itmCobExpr = hb_itemNew( hb_param( 2, HB_IT_BLOCK ) );
|
||||
hb_gcLockItem( dbRelations.itmCobExpr );
|
||||
dbRelations.abKey = hb_itemNew( hb_param( 3, HB_IT_STRING ) );
|
||||
dbRelations.isScoped = ( hb_pcount() > 3 )? hb_parl( 4 ):0;
|
||||
dbRelations.lpdbriNext = NULL;
|
||||
|
||||
@@ -1730,11 +1730,7 @@ static LPTAGINFO hb_ntxTagNew( LPNTXINDEX PIF, char * ITN, char *szKeyExpr, PHB_
|
||||
strcpy( pTag->ForExpr, szForExp );
|
||||
}
|
||||
pTag->pKeyItem = pKeyExpr;
|
||||
if( pTag->pKeyItem )
|
||||
hb_gcLockItem( pTag->pKeyItem );
|
||||
pTag->pForItem = pForExp;
|
||||
if( pTag->pForItem )
|
||||
hb_gcLockItem( pTag->pForItem );
|
||||
pTag->AscendKey = fAscendKey;
|
||||
pTag->UniqueKey = fUnique;
|
||||
pTag->KeyType = bKeyType;
|
||||
@@ -1777,14 +1773,12 @@ static void hb_ntxIndexFree( LPNTXINDEX pIndex )
|
||||
hb_xfree( pTag->ForExpr );
|
||||
if( pTag->pKeyItem != NULL )
|
||||
{
|
||||
hb_gcUnlockItem( pTag->pKeyItem );
|
||||
if( hb_itemType( pTag->pKeyItem ) != HB_IT_BLOCK )
|
||||
hb_macroDelete( ( HB_MACRO_PTR ) hb_itemGetPtr( pTag->pKeyItem ) );
|
||||
hb_itemRelease( pTag->pKeyItem );
|
||||
}
|
||||
if( pTag->pForItem != NULL )
|
||||
{
|
||||
hb_gcUnlockItem( pTag->pForItem );
|
||||
hb_itemRelease( pTag->pForItem );
|
||||
}
|
||||
hb_ntxKeyFree( pTag->CurKeyInfo );
|
||||
@@ -1821,7 +1815,6 @@ static ERRCODE hb_ntxHeaderLoad( LPNTXINDEX pIndex , char *ITN)
|
||||
pTag->KeyExpr = (char *) hb_xgrab( NTX_MAX_KEY );
|
||||
strcpy( pTag->KeyExpr, Header.key_expr );
|
||||
pTag->pKeyItem = pKeyExp;
|
||||
hb_gcLockItem( pTag->pKeyItem );
|
||||
pTag->AscendKey = 1; /* fAscendKey; */
|
||||
pTag->UniqueKey = Header.unique;
|
||||
pTag->KeyType = 'C'; /* bKeyType; */
|
||||
|
||||
@@ -500,17 +500,14 @@ ERRCODE hb_waOrderCondition( AREAP pArea, LPDBORDERCONDINFO param )
|
||||
hb_xfree( pArea->lpdbOrdCondInfo->abFor );
|
||||
if( pArea->lpdbOrdCondInfo->itmCobFor )
|
||||
{
|
||||
hb_gcUnlockItem( pArea->lpdbOrdCondInfo->itmCobFor );
|
||||
hb_itemRelease( pArea->lpdbOrdCondInfo->itmCobFor );
|
||||
}
|
||||
if( pArea->lpdbOrdCondInfo->itmCobWhile )
|
||||
{
|
||||
hb_gcUnlockItem( pArea->lpdbOrdCondInfo->itmCobWhile );
|
||||
hb_itemRelease( pArea->lpdbOrdCondInfo->itmCobWhile );
|
||||
}
|
||||
if( pArea->lpdbOrdCondInfo->itmCobEval )
|
||||
{
|
||||
hb_gcUnlockItem( pArea->lpdbOrdCondInfo->itmCobEval );
|
||||
hb_itemRelease( pArea->lpdbOrdCondInfo->itmCobEval );
|
||||
}
|
||||
hb_xfree( pArea->lpdbOrdCondInfo );
|
||||
@@ -706,7 +703,6 @@ ERRCODE hb_waClearRel( AREAP pArea )
|
||||
|
||||
if( lpdbRelation->itmCobExpr )
|
||||
{
|
||||
hb_gcUnlockItem( lpdbRelation->itmCobExpr );
|
||||
hb_itemRelease( lpdbRelation->itmCobExpr );
|
||||
}
|
||||
if( lpdbRelation->abKey )
|
||||
@@ -829,7 +825,6 @@ ERRCODE hb_waClearFilter( AREAP pArea )
|
||||
/* Free all items */
|
||||
if( pArea->dbfi.itmCobExpr )
|
||||
{
|
||||
hb_gcUnlockItem(pArea->dbfi.itmCobExpr);
|
||||
hb_itemRelease( pArea->dbfi.itmCobExpr );
|
||||
pArea->dbfi.itmCobExpr = NULL;
|
||||
}
|
||||
@@ -852,7 +847,6 @@ ERRCODE hb_waClearLocate( AREAP pArea )
|
||||
/* Free all items */
|
||||
if( pArea->dbsi.itmCobFor )
|
||||
{
|
||||
hb_gcUnlockItem( pArea->dbsi.itmCobFor );
|
||||
hb_itemRelease( pArea->dbsi.itmCobFor );
|
||||
pArea->dbsi.itmCobFor = NULL;
|
||||
}
|
||||
@@ -863,7 +857,6 @@ ERRCODE hb_waClearLocate( AREAP pArea )
|
||||
}
|
||||
if( pArea->dbsi.itmCobWhile )
|
||||
{
|
||||
hb_gcUnlockItem( pArea->dbsi.itmCobWhile );
|
||||
hb_itemRelease( pArea->dbsi.itmCobWhile );
|
||||
pArea->dbsi.itmCobWhile = NULL;
|
||||
}
|
||||
@@ -917,7 +910,6 @@ ERRCODE hb_waSetFilter( AREAP pArea, LPDBFILTERINFO pFilterInfo )
|
||||
if( pFilterInfo->itmCobExpr )
|
||||
{
|
||||
pArea->dbfi.itmCobExpr = hb_itemNew( pFilterInfo->itmCobExpr );
|
||||
hb_gcLockItem(pArea->dbfi.itmCobExpr);
|
||||
}
|
||||
|
||||
if( pFilterInfo->abFilterText )
|
||||
@@ -939,7 +931,6 @@ ERRCODE hb_waSetLocate( AREAP pArea, LPDBSCOPEINFO pScopeInfo )
|
||||
if( pScopeInfo->itmCobFor )
|
||||
{
|
||||
pArea->dbsi.itmCobFor = hb_itemNew( pScopeInfo->itmCobFor );
|
||||
hb_gcLockItem( pArea->dbsi.itmCobFor );
|
||||
}
|
||||
|
||||
if( pScopeInfo->lpstrFor )
|
||||
@@ -948,7 +939,6 @@ ERRCODE hb_waSetLocate( AREAP pArea, LPDBSCOPEINFO pScopeInfo )
|
||||
if( pScopeInfo->itmCobWhile )
|
||||
{
|
||||
pArea->dbsi.itmCobWhile = hb_itemNew( pScopeInfo->itmCobWhile );
|
||||
hb_gcLockItem( pArea->dbsi.itmCobWhile );
|
||||
}
|
||||
|
||||
if( pScopeInfo->lpstrWhile )
|
||||
|
||||
@@ -109,10 +109,7 @@ HB_FUNC( ERRORBLOCK )
|
||||
|
||||
if( pNewErrorBlock )
|
||||
{
|
||||
if( HB_IS_BLOCK( &oldError ) )
|
||||
hb_gcUnlockItem( &oldError ); /* allow release for garbage collector */
|
||||
hb_itemCopy( &s_errorBlock, pNewErrorBlock );
|
||||
hb_gcLockItem( pNewErrorBlock ); /* lock it in case it is not stored inside of harbour variable */
|
||||
}
|
||||
|
||||
hb_itemReturn( &oldError );
|
||||
@@ -199,11 +196,6 @@ USHORT hb_errLaunch( PHB_ITEM pError )
|
||||
if( s_iLaunchCount == HB_ERROR_LAUNCH_MAX )
|
||||
hb_errInternal( HB_EI_ERRTOOMANY, NULL, NULL, NULL );
|
||||
|
||||
/* Lock an item to prevent deallocation by the GC - the error object
|
||||
* can be not assigned to any harbour level variable
|
||||
*/
|
||||
hb_gcLockItem( pError );
|
||||
|
||||
/* Launch the error handler: "lResult := EVAL( ErrorBlock(), oError )" */
|
||||
|
||||
s_iLaunchCount++;
|
||||
@@ -221,7 +213,6 @@ USHORT hb_errLaunch( PHB_ITEM pError )
|
||||
else
|
||||
pResult = hb_itemDo( &s_errorBlock, 1, pError );
|
||||
|
||||
hb_gcUnlockItem( pError );
|
||||
s_iLaunchCount--;
|
||||
|
||||
/* Check results */
|
||||
@@ -308,11 +299,6 @@ PHB_ITEM hb_errLaunchSubst( PHB_ITEM pError )
|
||||
if( s_iLaunchCount == HB_ERROR_LAUNCH_MAX )
|
||||
hb_errInternal( HB_EI_ERRTOOMANY, NULL, NULL, NULL );
|
||||
|
||||
/* Lock an item to prevent deallocation by the GC - the error object
|
||||
* can be not assigned to any harbour level variable
|
||||
*/
|
||||
hb_gcLockItem( pError );
|
||||
|
||||
/* Launch the error handler: "xResult := EVAL( ErrorBlock(), oError )" */
|
||||
|
||||
s_iLaunchCount++;
|
||||
@@ -330,7 +316,6 @@ PHB_ITEM hb_errLaunchSubst( PHB_ITEM pError )
|
||||
else
|
||||
pResult = hb_itemDo( &s_errorBlock, 1, pError );
|
||||
|
||||
hb_gcUnlockItem( pError );
|
||||
s_iLaunchCount--;
|
||||
|
||||
/* Check results */
|
||||
|
||||
@@ -58,8 +58,10 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
/* list of background tasks */
|
||||
static HB_ITEM_PTR s_pIdleTasks = NULL;
|
||||
/* list of background tasks
|
||||
* A pointer into an array of pointers to items with a codeblock
|
||||
*/
|
||||
static HB_ITEM_PTR * s_pIdleTasks = NULL;
|
||||
|
||||
/* flag to prevent recursive calls of hb_idleState() */
|
||||
static BOOL s_bIamIdle = FALSE;
|
||||
@@ -141,7 +143,7 @@ void hb_idleState( void )
|
||||
|
||||
if( s_pIdleTasks && s_uiIdleTask < s_uiIdleMaxTask )
|
||||
{
|
||||
hb_vmEvalBlock( s_pIdleTasks + s_uiIdleTask );
|
||||
hb_vmEvalBlock( s_pIdleTasks[ s_uiIdleTask ] );
|
||||
++s_uiIdleTask;
|
||||
s_bIamIdle = FALSE;
|
||||
return;
|
||||
@@ -177,13 +179,11 @@ void hb_idleShutDown( void )
|
||||
{
|
||||
if( s_pIdleTasks )
|
||||
{
|
||||
HB_ITEM_PTR pItem = s_pIdleTasks;
|
||||
while( s_uiIdleMaxTask-- )
|
||||
do
|
||||
{
|
||||
hb_gcUnlock( pItem->item.asBlock.value );
|
||||
hb_itemClear( pItem );
|
||||
++pItem;
|
||||
hb_itemRelease( s_pIdleTasks[ --s_uiIdleMaxTask ] );
|
||||
}
|
||||
while( s_uiIdleMaxTask );
|
||||
hb_xfree( s_pIdleTasks );
|
||||
s_pIdleTasks = NULL;
|
||||
}
|
||||
@@ -211,18 +211,18 @@ HB_FUNC( HB_IDLEADD )
|
||||
++s_uiIdleMaxTask;
|
||||
if( !s_pIdleTasks )
|
||||
{
|
||||
s_pIdleTasks = ( HB_ITEM_PTR ) hb_xgrab( sizeof( HB_ITEM ) );
|
||||
s_pIdleTasks = ( HB_ITEM_PTR * ) hb_xgrab( sizeof( HB_ITEM_PTR ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
s_pIdleTasks = ( HB_ITEM_PTR ) hb_xrealloc( s_pIdleTasks, sizeof( HB_ITEM ) * s_uiIdleMaxTask );
|
||||
s_pIdleTasks = ( HB_ITEM_PTR * ) hb_xrealloc( s_pIdleTasks, sizeof( HB_ITEM_PTR ) * s_uiIdleMaxTask );
|
||||
}
|
||||
hb_itemCopy( s_pIdleTasks + s_uiIdleMaxTask - 1, pBlock );
|
||||
/* prevent releasing if this block if it is no longer stored inside of
|
||||
* a harbour variable
|
||||
*/
|
||||
hb_gcLockItem( pBlock );
|
||||
/* store a copy of passed codeblock
|
||||
*/
|
||||
s_pIdleTasks[ s_uiIdleMaxTask - 1 ] = hb_itemNew( pBlock );
|
||||
|
||||
/* return a pointer as a handle to this idle task
|
||||
*/
|
||||
hb_retnl( ( ULONG ) pBlock->item.asBlock.value ); /* TODO: access to pointers from harbour code */
|
||||
}
|
||||
else
|
||||
@@ -238,14 +238,14 @@ HB_FUNC( HB_IDLEDEL )
|
||||
{
|
||||
SHORT iTask;
|
||||
ULONG ulID = hb_parnl( 1 ); /* TODO: access to pointers from harbour code */
|
||||
HB_ITEM_PTR pItem = s_pIdleTasks;
|
||||
HB_ITEM_PTR pItem;
|
||||
|
||||
iTask = 0;
|
||||
while( iTask < s_uiIdleMaxTask && !bFound )
|
||||
{
|
||||
pItem = s_pIdleTasks[ iTask ];
|
||||
if( ulID == ( ULONG ) pItem->item.asBlock.value )
|
||||
{
|
||||
hb_gcUnlockItem( pItem );
|
||||
hb_itemClear( hb_itemReturn( pItem ) ); /* return a codeblock */
|
||||
|
||||
--s_uiIdleMaxTask;
|
||||
@@ -253,8 +253,8 @@ HB_FUNC( HB_IDLEDEL )
|
||||
{
|
||||
if( iTask != s_uiIdleMaxTask )
|
||||
memcpy( &s_pIdleTasks[ iTask ], &s_pIdleTasks[ iTask + 1 ],
|
||||
sizeof( HB_ITEM ) * (s_uiIdleMaxTask - iTask) );
|
||||
s_pIdleTasks = ( HB_ITEM_PTR ) hb_xrealloc( s_pIdleTasks, sizeof( HB_ITEM ) * s_uiIdleMaxTask );
|
||||
sizeof( HB_ITEM_PTR ) * (s_uiIdleMaxTask - iTask) );
|
||||
s_pIdleTasks = ( HB_ITEM_PTR * ) hb_xrealloc( s_pIdleTasks, sizeof( HB_ITEM_PTR ) * s_uiIdleMaxTask );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -263,7 +263,6 @@ HB_FUNC( HB_IDLEDEL )
|
||||
}
|
||||
bFound = TRUE;
|
||||
}
|
||||
++pItem;
|
||||
++iTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,11 +65,9 @@ void hb_setkeyExit( void )
|
||||
{
|
||||
PHB_SETKEY sk_list_tmp;
|
||||
|
||||
hb_gcUnlockItem( s_sk_list->pAction );
|
||||
hb_itemRelease( s_sk_list->pAction );
|
||||
if( s_sk_list->pIsActive )
|
||||
{
|
||||
hb_gcUnlockItem( s_sk_list->pIsActive );
|
||||
hb_itemRelease( s_sk_list->pIsActive );
|
||||
}
|
||||
sk_list_tmp = s_sk_list->next;
|
||||
@@ -109,10 +107,6 @@ static void sk_add( BOOL bReturn, SHORT iKeyCode, PHB_ITEM pAction, PHB_ITEM pIs
|
||||
sk_list_tmp->iKeyCode = iKeyCode;
|
||||
sk_list_tmp->pAction = hb_itemNew( pAction );
|
||||
sk_list_tmp->pIsActive = pIsActive ? hb_itemNew( pIsActive ) : NULL;
|
||||
/* lock codeblock to prevent deallocation by the GC */
|
||||
hb_gcLockItem( sk_list_tmp->pAction );
|
||||
if( sk_list_tmp->pIsActive )
|
||||
hb_gcLockItem( sk_list_tmp->pIsActive );
|
||||
|
||||
if( sk_list_end == NULL )
|
||||
s_sk_list = sk_list_tmp;
|
||||
@@ -129,11 +123,9 @@ static void sk_add( BOOL bReturn, SHORT iKeyCode, PHB_ITEM pAction, PHB_ITEM pIs
|
||||
|
||||
/* Free the previous values */
|
||||
|
||||
hb_gcUnlockItem( sk_list_tmp->pAction );
|
||||
hb_itemRelease( sk_list_tmp->pAction );
|
||||
if( sk_list_tmp->pIsActive )
|
||||
{
|
||||
hb_gcUnlockItem( sk_list_tmp->pIsActive );
|
||||
hb_itemRelease( sk_list_tmp->pIsActive );
|
||||
}
|
||||
/* Set the new values or free the entry */
|
||||
@@ -142,10 +134,6 @@ static void sk_add( BOOL bReturn, SHORT iKeyCode, PHB_ITEM pAction, PHB_ITEM pIs
|
||||
{
|
||||
sk_list_tmp->pAction = hb_itemNew( pAction );
|
||||
sk_list_tmp->pIsActive = pIsActive ? hb_itemNew( pIsActive ) : NULL;
|
||||
/* lock codeblock to prevent deallocation by the GC */
|
||||
hb_gcLockItem( sk_list_tmp->pAction );
|
||||
if( sk_list_tmp->pIsActive )
|
||||
hb_gcLockItem( sk_list_tmp->pIsActive );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -146,6 +146,58 @@ void hb_gcFree( void *pBlock )
|
||||
}
|
||||
}
|
||||
|
||||
static HB_GARBAGE_FUNC( hb_gcGripRelease )
|
||||
{
|
||||
/* Item was already released in hb_gcGripDrop() - then we have nothing
|
||||
* to do here
|
||||
*/
|
||||
HB_SYMBOL_UNUSED( Cargo );
|
||||
}
|
||||
|
||||
HB_ITEM_PTR hb_gcGripGet( HB_ITEM_PTR pOrigin )
|
||||
{
|
||||
HB_GARBAGE_PTR pAlloc;
|
||||
|
||||
pAlloc = HB_GARBAGE_NEW( sizeof( HB_ITEM ) + sizeof( HB_GARBAGE ) );
|
||||
if( pAlloc )
|
||||
{
|
||||
HB_ITEM_PTR pItem = ( HB_ITEM_PTR )( pAlloc + 1 );
|
||||
|
||||
hb_gcLink( &s_pLockedBlock, pAlloc );
|
||||
pAlloc->pFunc = hb_gcGripRelease;
|
||||
pAlloc->locked = 1;
|
||||
pAlloc->used = s_uUsedFlag;
|
||||
if( pOrigin )
|
||||
{
|
||||
pItem->type = HB_IT_NIL;
|
||||
hb_itemCopy( pItem, pOrigin );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( pItem, 0, sizeof( HB_ITEM ) );
|
||||
pItem->type = HB_IT_NIL;
|
||||
}
|
||||
|
||||
return pItem;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hb_gcGripDrop( HB_ITEM_PTR pItem )
|
||||
{
|
||||
if( pItem )
|
||||
{
|
||||
HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) pItem;
|
||||
--pAlloc;
|
||||
|
||||
hb_itemClear( pItem ); /* clear value stored in this item */
|
||||
|
||||
hb_gcUnlink( &s_pLockedBlock, pAlloc );
|
||||
HB_GARBAGE_FREE( pAlloc );
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock a memory pointer so it will not be released if stored
|
||||
outside of harbour variables
|
||||
*/
|
||||
@@ -190,29 +242,6 @@ void *hb_gcUnlock( void *pBlock )
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
|
||||
/* Lock an item so it will not be released if stored
|
||||
outside of harbour variables
|
||||
*/
|
||||
void hb_gcLockItem( HB_ITEM_PTR pItem )
|
||||
{
|
||||
if( HB_IS_ARRAY( pItem ) )
|
||||
hb_gcLock( pItem->item.asArray.value );
|
||||
else if( HB_IS_BLOCK( pItem ) )
|
||||
hb_gcLock( pItem->item.asBlock.value );
|
||||
}
|
||||
|
||||
/* Unlock an item so it can be released if there is no
|
||||
references inside of harbour variables
|
||||
*/
|
||||
void hb_gcUnlockItem( HB_ITEM_PTR pItem )
|
||||
{
|
||||
if( HB_IS_ARRAY( pItem ) )
|
||||
hb_gcUnlock( pItem->item.asArray.value );
|
||||
else if( HB_IS_BLOCK( pItem ) )
|
||||
hb_gcUnlock( pItem->item.asBlock.value );
|
||||
}
|
||||
|
||||
/* Mark a passed item as used so it will be not released by the GC
|
||||
*/
|
||||
void hb_gcItemRef( HB_ITEM_PTR pItem )
|
||||
@@ -304,31 +333,9 @@ void hb_gcCollectAll( void )
|
||||
pAlloc = s_pLockedBlock;
|
||||
do
|
||||
{ /* it is not very elegant method but it works well */
|
||||
if( pAlloc->pFunc == hb_arrayReleaseGarbage )
|
||||
if( pAlloc->pFunc == hb_gcGripRelease )
|
||||
{
|
||||
HB_BASEARRAY_PTR pArray = ( HB_BASEARRAY_PTR ) ( pAlloc + 1 );
|
||||
ULONG ulSize = pArray->ulLen;
|
||||
HB_ITEM_PTR pItem;
|
||||
|
||||
/* mark as used all elements in locked array */
|
||||
pItem = pArray->pItems;
|
||||
while( ulSize )
|
||||
{
|
||||
hb_gcItemRef( pItem++ );
|
||||
--ulSize;
|
||||
}
|
||||
} /* it is not very elegant method but it works well */
|
||||
else if( pAlloc->pFunc == hb_codeblockDeleteGarbage )
|
||||
{
|
||||
HB_CODEBLOCK_PTR pCBlock = ( HB_CODEBLOCK_PTR ) ( pAlloc + 1 );
|
||||
USHORT ui = 1;
|
||||
|
||||
/* mark as used all detached variables in locked codeblock */
|
||||
while( ui <= pCBlock->uiLocals )
|
||||
{
|
||||
hb_gcItemRef( &pCBlock->pLocals[ ui ] );
|
||||
++ui;
|
||||
}
|
||||
hb_gcItemRef( ( HB_ITEM_PTR ) ( pAlloc + 1 ) );
|
||||
}
|
||||
pAlloc = pAlloc->pNext;
|
||||
} while ( s_pLockedBlock != pAlloc );
|
||||
|
||||
@@ -322,24 +322,9 @@ PHB_ITEM hb_itemDoC( char * szFunc, USHORT uiPCount, PHB_ITEM pItemArg1, ... )
|
||||
|
||||
PHB_ITEM hb_itemNew( PHB_ITEM pNull )
|
||||
{
|
||||
PHB_ITEM pItem;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_itemNew(%p)", pNull));
|
||||
|
||||
pItem = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) );
|
||||
|
||||
if( pNull )
|
||||
{
|
||||
pItem->type = HB_IT_NIL;
|
||||
hb_itemCopy( pItem, pNull );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( pItem, 0, sizeof( HB_ITEM ) );
|
||||
pItem->type = HB_IT_NIL;
|
||||
}
|
||||
|
||||
return pItem;
|
||||
return hb_gcGripGet( pNull );
|
||||
}
|
||||
|
||||
PHB_ITEM hb_itemParam( USHORT uiParam )
|
||||
@@ -380,9 +365,7 @@ BOOL hb_itemRelease( PHB_ITEM pItem )
|
||||
|
||||
if( pItem )
|
||||
{
|
||||
hb_itemClear( pItem );
|
||||
hb_xfree( pItem );
|
||||
|
||||
hb_gcGripDrop( pItem );
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user