Пример #1
0
/* Unlock a memory pointer so it can be released if there is no
   references inside of harbour variables
 */
void * hb_gcUnlock( void * pBlock )
{
   if( pBlock )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock );

      if( pAlloc->locked )
      {
         HB_GC_LOCK();
         if( pAlloc->locked )
         {
            if( --pAlloc->locked == 0 )
            {
               pAlloc->used = s_uUsedFlag;

               hb_gcUnlink( &s_pLockedBlock, pAlloc );
               hb_gcLink( &s_pCurrBlock, pAlloc );
               HB_GC_AUTO_INC();
            }
         }
         HB_GC_UNLOCK();
      }
   }
   return pBlock;
}
Пример #2
0
/* release a memory block allocated with hb_gcAlloc*() */
void hb_gcFree( void * pBlock )
{
   if( pBlock )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock );

      /* Don't release the block that will be deleted during finalization */
      if( ! ( pAlloc->used & HB_GC_DELETE ) )
      {
         HB_GC_LOCK();
         if( pAlloc->locked )
            hb_gcUnlink( &s_pLockedBlock, pAlloc );
         else
         {
            hb_gcUnlink( &s_pCurrBlock, pAlloc );
            HB_GC_AUTO_DEC();
         }
         HB_GC_UNLOCK();

         HB_GARBAGE_FREE( pAlloc );
      }
   }
   else
   {
      hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL );
   }
}
Пример #3
0
/* mark passed memory block as used so it will be not released by the GC */
void hb_gcMark( void * pBlock )
{
   PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock );

   if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag )
   {
      pAlloc->used ^= HB_GC_USED_FLAG;  /* mark this codeblock as used */
      pAlloc->pFuncs->mark( pBlock );
   }
}
Пример #4
0
void hb_gcRefFree( void * pBlock )
{
   if( pBlock )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock );

      if( hb_xRefDec( pAlloc ) )
      {
         /* Don't release the block that will be deleted during finalization */
         if( ! ( pAlloc->used & HB_GC_DELETE ) )
         {
            pAlloc->used |= HB_GC_DELETE;

            /* execute clean-up function */
            pAlloc->pFuncs->clear( pBlock );

            if( hb_xRefCount( pAlloc ) != 0 )
            {
               if( pAlloc->used & HB_GC_DELETE )
               {
                  pAlloc->used = s_uUsedFlag;
                  if( hb_vmRequestQuery() == 0 )
                     hb_errRT_BASE( EG_DESTRUCTOR, 1301, NULL, "Reference to freed block", 0 );
               }
            }
            else
            {
               HB_GC_LOCK();
               if( pAlloc->locked )
                  hb_gcUnlink( &s_pLockedBlock, pAlloc );
               else
               {
                  hb_gcUnlink( &s_pCurrBlock, pAlloc );
                  HB_GC_AUTO_DEC();
               }
               HB_GC_UNLOCK();
               HB_GARBAGE_FREE( pAlloc );
            }
         }
      }
   }
   else
   {
      hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL );
   }
}
Пример #5
0
/* Lock a memory pointer so it will not be released if stored
   outside of harbour variables
 */
void * hb_gcLock( void * pBlock )
{
   if( pBlock )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock );

      HB_GC_LOCK();
      if( ! pAlloc->locked )
      {
         hb_gcUnlink( &s_pCurrBlock, pAlloc );
         hb_gcLink( &s_pLockedBlock, pAlloc );
         HB_GC_AUTO_DEC();
      }
      ++pAlloc->locked;
      HB_GC_UNLOCK();
   }

   return pBlock;
}
Пример #6
0
void hb_gcAttach( void * pBlock )
{
   PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock );

   if( pAlloc->locked )
   {
      HB_GC_LOCK();
      if( pAlloc->locked )
      {
         if( --pAlloc->locked == 0 )
         {
            pAlloc->used = s_uUsedFlag;

            hb_gcUnlink( &s_pLockedBlock, pAlloc );
            hb_gcLink( &s_pCurrBlock, pAlloc );
            HB_GC_AUTO_INC();
            pAlloc = NULL;
         }
      }
      HB_GC_UNLOCK();
   }
   if( pAlloc )
      hb_xRefInc( pAlloc );
}
Пример #7
0
/* Mark a passed item as used so it will be not released by the GC
 */
void hb_gcItemRef( PHB_ITEM pItem )
{
   while( HB_IS_BYREF( pItem ) )
   {
      if( HB_IS_ENUM( pItem ) )
         return;
      else if( HB_IS_EXTREF( pItem ) )
      {
         pItem->item.asExtRef.func->mark( pItem->item.asExtRef.value );
         return;
      }
      else if( ! HB_IS_MEMVAR( pItem ) &&
               pItem->item.asRefer.offset == 0 &&
               pItem->item.asRefer.value >= 0 )
      {
         /* array item reference */
         PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asRefer.BasePtr.array );
         if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag )
         {
            /* mark this array as used */
            pAlloc->used ^= HB_GC_USED_FLAG;
            /* mark also all array elements */
            pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) );
         }
         return;
      }
      pItem = hb_itemUnRefOnce( pItem );
   }

   if( HB_IS_ARRAY( pItem ) )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asArray.value );

      /* Check this array only if it was not checked yet */
      if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag )
      {
         /* mark this array as used so it will be no re-checked from
          * other references
          */
         pAlloc->used ^= HB_GC_USED_FLAG;
         /* mark also all array elements */
         pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) );
      }
   }
   else if( HB_IS_HASH( pItem ) )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asHash.value );

      /* Check this hash table only if it was not checked yet */
      if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag )
      {
         /* mark this hash table as used */
         pAlloc->used ^= HB_GC_USED_FLAG;
         /* mark also all hash elements */
         pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) );
      }
   }
   else if( HB_IS_BLOCK( pItem ) )
   {
      PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asBlock.value );

      if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag )
      {
         /* mark this codeblock as used */
         pAlloc->used ^= HB_GC_USED_FLAG;
         /* mark as used all detached variables in a codeblock */
         pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) );
      }
   }
   else if( HB_IS_POINTER( pItem ) )
   {
      if( pItem->item.asPointer.collect )
      {
         PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asPointer.value );

         if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag )
         {
            /* mark this memory block as used */
            pAlloc->used ^= HB_GC_USED_FLAG;
            /* mark also all internal user blocks attached to this block */
            pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) );
         }
      }
   }
   /* all other data types don't need the GC */
}
Пример #8
0
HB_COUNTER hb_gcRefCount( void * pBlock )
{
   return hb_xRefCount( HB_GC_PTR( pBlock ) );
}
Пример #9
0
void hb_gcRefInc( void * pBlock )
{
   hb_xRefInc( HB_GC_PTR( pBlock ) );
}
Пример #10
0
/* return cleanup function pointer */
const HB_GC_FUNCS * hb_gcFuncs( void * pBlock )
{
   return HB_GC_PTR( pBlock )->pFuncs;
}
Пример #11
0
/* return cleanup function pointer */
HB_GARBAGE_FUNC_PTR hb_gcFunc( void *pBlock )
{
   return HB_GC_PTR( pBlock )->pFunc;
}