2008-09-19 22:27 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/source/vm/set.c
! fixed casting
* harbour/contrib/xhb/xhbcopyf.c
* replaced TABs with SPACEs
* harbour/include/hbapirdd.h
* harbour/source/rdd/workarea.c
* harbour/source/rdd/wacore.c
* harbour/source/rdd/wafunc.c
+ added support for detaching and attaching workareas
* harbour/source/vm/hvm.c
% minor cleanup in thread return code
* harbour/include/hbthread.h
* harbour/source/vm/thread.c
* unlock HVM stack during thread join operation
* added workaround for DosWaitThread() which seems to fail if thread
terminated before
; added TOFIX note for OS2 and join code
This commit is contained in:
@@ -8,6 +8,29 @@
|
||||
2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
|
||||
*/
|
||||
|
||||
2008-09-19 22:27 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/source/vm/set.c
|
||||
! fixed casting
|
||||
|
||||
* harbour/contrib/xhb/xhbcopyf.c
|
||||
* replaced TABs with SPACEs
|
||||
|
||||
* harbour/include/hbapirdd.h
|
||||
* harbour/source/rdd/workarea.c
|
||||
* harbour/source/rdd/wacore.c
|
||||
* harbour/source/rdd/wafunc.c
|
||||
+ added support for detaching and attaching workareas
|
||||
|
||||
* harbour/source/vm/hvm.c
|
||||
% minor cleanup in thread return code
|
||||
|
||||
* harbour/include/hbthread.h
|
||||
* harbour/source/vm/thread.c
|
||||
* unlock HVM stack during thread join operation
|
||||
* added workaround for DosWaitThread() which seems to fail if thread
|
||||
terminated before
|
||||
; added TOFIX note for OS2 and join code
|
||||
|
||||
2008-09-19 12:21 UTC+0100 Miguel Angel Marchuet <miguelangel@marchuet.net>
|
||||
* contrib/hbbmcdx/bmdbfcdx.c
|
||||
* source/rdd/dbfcdx/dbfcdx1.c
|
||||
|
||||
@@ -102,7 +102,7 @@ static BOOL hb_fsCopy( char * szSource, char * szDest, PHB_ITEM pBlock )
|
||||
bRetVal = TRUE;
|
||||
|
||||
if( hb_itemType( pBlock ) != HB_IT_BLOCK )
|
||||
pBlock = NULL;
|
||||
pBlock = NULL;
|
||||
|
||||
while( ( usRead = hb_fsRead( fhndSource, buffer, BUFFER_SIZE ) ) != 0 )
|
||||
{
|
||||
|
||||
@@ -1149,8 +1149,12 @@ typedef RDDNODE * LPRDDNODE;
|
||||
* PROTOTYPES
|
||||
* ----------
|
||||
*/
|
||||
/* RDD virtual machine integration functions */
|
||||
|
||||
|
||||
/* internal RDD functions */
|
||||
extern void hb_rddCloseDetachedAreas( void );
|
||||
|
||||
/* RDD virtual machine integration functions */
|
||||
extern HB_EXPORT void hb_rddShutDown( void );
|
||||
extern HB_EXPORT ERRCODE hb_rddGetFieldValue( HB_ITEM_PTR pItem, PHB_SYMB pFieldSymbol );
|
||||
extern HB_EXPORT ERRCODE hb_rddPutFieldValue( HB_ITEM_PTR pItem, PHB_SYMB pFieldSymbol );
|
||||
@@ -1214,6 +1218,11 @@ extern HB_EXPORT ERRCODE hb_rddTransRecords(
|
||||
const char *szCpId,
|
||||
PHB_ITEM pDelim );
|
||||
extern HB_EXPORT void hb_tblStructure( AREAP pArea, PHB_ITEM pStruct, USHORT uiSize );
|
||||
extern HB_EXPORT ERRCODE hb_rddCloseAllParentRelations( AREAP pArea );
|
||||
|
||||
extern HB_EXPORT ERRCODE hb_rddDetachArea( AREAP pArea, PHB_ITEM pCargo );
|
||||
extern HB_EXPORT AREAP hb_rddRequestArea( char * szAlias, PHB_ITEM pCargo,
|
||||
BOOL fNewArea, BOOL fWait );
|
||||
|
||||
#if 0
|
||||
extern HB_EXPORT ERRCODE hb_rddDisinherit( const char * drvName );
|
||||
|
||||
@@ -301,7 +301,7 @@ extern void hb_threadMutexNotify( PHB_ITEM pItem, PHB_ITEM pNotifier, BOOL f
|
||||
extern PHB_ITEM hb_threadMutexSubscribe( PHB_ITEM pItem, BOOL fClear );
|
||||
extern PHB_ITEM hb_threadMutexTimedSubscribe( PHB_ITEM pItem, ULONG ulMilliSec, BOOL fClear );
|
||||
|
||||
#if defined( HB_MT_VM ) && defined( _HB_API_INTERNAL_ ) /* && defined( HB_STACK_MACROS ) */
|
||||
#if defined( HB_MT_VM ) && defined( _HB_API_INTERNAL_ )
|
||||
|
||||
extern void hb_threadMutexUnlockAll( void );
|
||||
|
||||
|
||||
@@ -57,21 +57,8 @@
|
||||
#include "hbapierr.h"
|
||||
#include "hbvm.h"
|
||||
#include "hbstack.h"
|
||||
#include "hbthread.h"
|
||||
|
||||
#if 0
|
||||
/* Default RDD name */
|
||||
static AREAP * s_waList = NULL; /* Allocated WorkAreas */
|
||||
static USHORT s_uiWaMax = 0; /* Number of allocated WA */
|
||||
static USHORT s_uiWaSpace = 0; /* Number of allocated WA */
|
||||
|
||||
static USHORT * s_waNums = NULL; /* Allocated WorkAreas */
|
||||
static USHORT s_uiWaNumMax = 0; /* Number of allocated WA */
|
||||
|
||||
static USHORT s_uiCurrArea = 1; /* Current WokrArea number */
|
||||
static AREAP s_pCurrArea = NULL; /* Current WorkArea pointer */
|
||||
|
||||
static BOOL s_fNetError = FALSE; /* Error on Networked environments */
|
||||
#endif
|
||||
|
||||
#define HB_SET_WA( n ) do \
|
||||
{ \
|
||||
@@ -83,59 +70,11 @@ static BOOL s_fNetError = FALSE; /* Error on Networked environments */
|
||||
|
||||
|
||||
/*
|
||||
* Return the next free WorkArea for later use.
|
||||
* Insert new WorkArea node at current WA position
|
||||
*/
|
||||
HB_EXPORT ERRCODE hb_rddSelectFirstAvailable( void )
|
||||
static void hb_waNodeInsert( PHB_STACKRDD pRddInfo, AREAP pArea )
|
||||
{
|
||||
PHB_STACKRDD pRddInfo;
|
||||
USHORT uiArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddSelectFirstAvailable()"));
|
||||
|
||||
pRddInfo = hb_stackRDD();
|
||||
|
||||
uiArea = 1;
|
||||
while( uiArea < pRddInfo->uiWaNumMax )
|
||||
{
|
||||
if( pRddInfo->waNums[ uiArea ] == 0 )
|
||||
break;
|
||||
uiArea++;
|
||||
}
|
||||
if( uiArea >= HB_RDD_MAX_AREA_NUM )
|
||||
return FAILURE;
|
||||
HB_SET_WA( uiArea );
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the new WorkArea node
|
||||
*/
|
||||
HB_EXPORT USHORT hb_rddInsertAreaNode( const char *szDriver )
|
||||
{
|
||||
USHORT uiRddID, uiWaPos;
|
||||
PHB_STACKRDD pRddInfo;
|
||||
LPRDDNODE pRddNode;
|
||||
AREAP pArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddInsertAreaNode(%s)", szDriver));
|
||||
|
||||
pRddInfo = hb_stackRDD();
|
||||
if( pRddInfo->uiCurrArea && pRddInfo->pCurrArea )
|
||||
return 0;
|
||||
|
||||
pRddNode = hb_rddFindNode( szDriver, &uiRddID );
|
||||
if( !pRddNode )
|
||||
return 0;
|
||||
|
||||
pArea = ( AREAP ) hb_rddNewAreaNode( pRddNode, uiRddID );
|
||||
if( !pArea )
|
||||
return 0;
|
||||
|
||||
if( pRddInfo->uiCurrArea == 0 )
|
||||
{
|
||||
if( hb_rddSelectFirstAvailable() != SUCCESS )
|
||||
return 0;
|
||||
}
|
||||
USHORT uiWaPos;
|
||||
|
||||
if( pRddInfo->uiCurrArea >= pRddInfo->uiWaNumMax )
|
||||
{
|
||||
@@ -183,35 +122,17 @@ HB_EXPORT USHORT hb_rddInsertAreaNode( const char *szDriver )
|
||||
uiWaPos--;
|
||||
}
|
||||
}
|
||||
pRddInfo->waList[ uiWaPos ] = pArea;
|
||||
pRddInfo->waNums[ pRddInfo->uiCurrArea ] = uiWaPos;
|
||||
pRddInfo->pCurrArea = pRddInfo->waList[ uiWaPos ];
|
||||
( ( AREAP ) pRddInfo->pCurrArea )->uiArea = pRddInfo->uiCurrArea;
|
||||
|
||||
return pRddInfo->uiCurrArea;
|
||||
pRddInfo->pCurrArea = pRddInfo->waList[ uiWaPos ] = pArea;
|
||||
pArea->uiArea = pRddInfo->uiCurrArea;
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes and releases the current WorkArea preparing it
|
||||
* to be used with a new database.
|
||||
* Remove current WorkArea node
|
||||
*/
|
||||
HB_EXPORT void hb_rddReleaseCurrentArea( void )
|
||||
static void hb_waNodeDelete( PHB_STACKRDD pRddInfo )
|
||||
{
|
||||
PHB_STACKRDD pRddInfo;
|
||||
USHORT uiWaPos;
|
||||
AREAP pArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddReleaseCurrentArea()"));
|
||||
|
||||
pRddInfo = hb_stackRDD();
|
||||
pArea = ( AREAP ) pRddInfo->pCurrArea;
|
||||
if( !pArea )
|
||||
return;
|
||||
|
||||
if( SELF_CLOSE( pArea ) == FAILURE )
|
||||
return;
|
||||
|
||||
SELF_RELEASE( pArea );
|
||||
|
||||
uiWaPos = pRddInfo->waNums[ pRddInfo->uiCurrArea ];
|
||||
pRddInfo->waNums[ pRddInfo->uiCurrArea ] = 0;
|
||||
@@ -242,6 +163,90 @@ HB_EXPORT void hb_rddReleaseCurrentArea( void )
|
||||
pRddInfo->pCurrArea = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next free WorkArea for later use.
|
||||
*/
|
||||
HB_EXPORT ERRCODE hb_rddSelectFirstAvailable( void )
|
||||
{
|
||||
PHB_STACKRDD pRddInfo;
|
||||
USHORT uiArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddSelectFirstAvailable()"));
|
||||
|
||||
pRddInfo = hb_stackRDD();
|
||||
|
||||
uiArea = 1;
|
||||
while( uiArea < pRddInfo->uiWaNumMax )
|
||||
{
|
||||
if( pRddInfo->waNums[ uiArea ] == 0 )
|
||||
break;
|
||||
uiArea++;
|
||||
}
|
||||
if( uiArea >= HB_RDD_MAX_AREA_NUM )
|
||||
return FAILURE;
|
||||
HB_SET_WA( uiArea );
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creare and insert the new WorkArea node
|
||||
*/
|
||||
HB_EXPORT USHORT hb_rddInsertAreaNode( const char *szDriver )
|
||||
{
|
||||
PHB_STACKRDD pRddInfo;
|
||||
LPRDDNODE pRddNode;
|
||||
USHORT uiRddID;
|
||||
AREAP pArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddInsertAreaNode(%s)", szDriver));
|
||||
|
||||
pRddInfo = hb_stackRDD();
|
||||
if( pRddInfo->uiCurrArea && pRddInfo->pCurrArea )
|
||||
return 0;
|
||||
|
||||
pRddNode = hb_rddFindNode( szDriver, &uiRddID );
|
||||
if( !pRddNode )
|
||||
return 0;
|
||||
|
||||
pArea = ( AREAP ) hb_rddNewAreaNode( pRddNode, uiRddID );
|
||||
if( !pArea )
|
||||
return 0;
|
||||
|
||||
if( pRddInfo->uiCurrArea == 0 )
|
||||
{
|
||||
if( hb_rddSelectFirstAvailable() != SUCCESS )
|
||||
return 0;
|
||||
}
|
||||
|
||||
hb_waNodeInsert( pRddInfo, pArea );
|
||||
|
||||
return pRddInfo->uiCurrArea;
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes and releases the current WorkArea preparing it
|
||||
* to be used with a new database.
|
||||
*/
|
||||
HB_EXPORT void hb_rddReleaseCurrentArea( void )
|
||||
{
|
||||
PHB_STACKRDD pRddInfo;
|
||||
AREAP pArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddReleaseCurrentArea()"));
|
||||
|
||||
pRddInfo = hb_stackRDD();
|
||||
pArea = ( AREAP ) pRddInfo->pCurrArea;
|
||||
if( !pArea )
|
||||
return;
|
||||
|
||||
if( SELF_CLOSE( pArea ) == FAILURE )
|
||||
return;
|
||||
|
||||
SELF_RELEASE( pArea );
|
||||
|
||||
hb_waNodeDelete( pRddInfo );
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes all WorkAreas.
|
||||
*/
|
||||
@@ -446,3 +451,196 @@ HB_EXPORT ERRCODE hb_rddSelectWorkAreaNumber( int iArea )
|
||||
|
||||
return ( pRddInfo->pCurrArea == NULL ) ? FAILURE : SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* *********************************************************** */
|
||||
|
||||
/*
|
||||
* Moving work ares between threads
|
||||
*/
|
||||
|
||||
static HB_CRITICAL_NEW( s_waMtx );
|
||||
static HB_COND_NEW( s_waCond );
|
||||
static PHB_ITEM s_pDetachedAreas = NULL;
|
||||
|
||||
static HB_GARBAGE_FUNC( hb_waHolderDestructor )
|
||||
{
|
||||
AREAP * pHolder = ( AREAP * ) Cargo;
|
||||
|
||||
if( *pHolder )
|
||||
{
|
||||
AREAP pArea;
|
||||
int iArea;
|
||||
|
||||
pArea = *pHolder;
|
||||
*pHolder = NULL;
|
||||
|
||||
iArea = hb_rddGetCurrentWorkAreaNumber();
|
||||
|
||||
hb_rddSelectFirstAvailable();
|
||||
hb_waNodeInsert( hb_stackRDD(), pArea );
|
||||
hb_rddReleaseCurrentArea();
|
||||
|
||||
hb_rddSelectWorkAreaNumber( iArea );
|
||||
}
|
||||
}
|
||||
|
||||
void hb_rddCloseDetachedAreas( void )
|
||||
{
|
||||
PHB_ITEM pDetachedArea;
|
||||
|
||||
/* protect by critical section access to s_pDetachedAreas array */
|
||||
hb_threadEnterCriticalSection( &s_waMtx );
|
||||
pDetachedArea = s_pDetachedAreas;
|
||||
s_pDetachedAreas = NULL;
|
||||
/* leave critical section */
|
||||
hb_threadLeaveCriticalSection( &s_waMtx );
|
||||
/* release detached areas */
|
||||
if( pDetachedArea )
|
||||
hb_itemRelease( pDetachedArea );
|
||||
}
|
||||
|
||||
HB_EXPORT ERRCODE hb_rddDetachArea( AREAP pArea, PHB_ITEM pCargo )
|
||||
{
|
||||
AREAP * pHolder;
|
||||
PHB_ITEM pDetachedArea;
|
||||
ULONG ulPos;
|
||||
int iArea;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddDetachArea(%p,%p)", pArea, pCargo));
|
||||
|
||||
/* save current WA number */
|
||||
iArea = hb_rddGetCurrentWorkAreaNumber();
|
||||
/* select given WA */
|
||||
hb_rddSelectWorkAreaNumber( pArea->uiArea );
|
||||
/* flush buffers */
|
||||
SELF_GOCOLD( pArea );
|
||||
/* remove all locks */
|
||||
/* ??? is it xbase++ compatible? */
|
||||
/* SELF_UNLOCK( pArea, NULL ); */
|
||||
/* Clear all child and parent relations */
|
||||
SELF_CLEARREL( pArea );
|
||||
hb_rddCloseAllParentRelations( pArea );
|
||||
/* detach WA and alias */
|
||||
hb_waNodeDelete( hb_stackRDD() );
|
||||
pArea->uiArea = 0;
|
||||
if( pArea->atomAlias )
|
||||
hb_dynsymSetAreaHandle( ( PHB_DYNS ) pArea->atomAlias, 0 );
|
||||
/* restore previous WA number */
|
||||
hb_rddSelectWorkAreaNumber( iArea );
|
||||
|
||||
/* protect by critical section access to s_pDetachedAreas array */
|
||||
hb_threadEnterCriticalSection( &s_waMtx );
|
||||
if( ! s_pDetachedAreas )
|
||||
{
|
||||
s_pDetachedAreas = hb_itemArrayNew( 1 );
|
||||
ulPos = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulPos = hb_arrayLen( s_pDetachedAreas ) + 1;
|
||||
hb_arraySize( s_pDetachedAreas, ulPos );
|
||||
}
|
||||
pDetachedArea = hb_arrayGetItemPtr( s_pDetachedAreas, ulPos );
|
||||
hb_arrayNew( pDetachedArea, 2 );
|
||||
if( pCargo )
|
||||
hb_arraySet( pDetachedArea, 2, pCargo );
|
||||
pHolder = ( AREAP * ) hb_gcAlloc( sizeof( AREAP ), hb_waHolderDestructor );
|
||||
*pHolder = pArea;
|
||||
hb_itemPutPtrGC( hb_arrayGetItemPtr( pDetachedArea, 1 ), pHolder );
|
||||
/* siagnal waiting processes that new area is available */
|
||||
hb_threadCondBroadcast( &s_waCond );
|
||||
/* leave critical section */
|
||||
hb_threadLeaveCriticalSection( &s_waMtx );
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
HB_EXPORT AREAP hb_rddRequestArea( char * szAlias, PHB_ITEM pCargo,
|
||||
BOOL fNewArea, BOOL fWait )
|
||||
{
|
||||
PHB_DYNS pSymAlias = NULL;
|
||||
AREAP pArea = NULL;
|
||||
|
||||
if( pCargo )
|
||||
hb_itemClear( pCargo );
|
||||
|
||||
/* close current WA or chose 1-st free available */
|
||||
if( !fNewArea )
|
||||
{
|
||||
hb_rddReleaseCurrentArea();
|
||||
}
|
||||
else if( hb_rddSelectFirstAvailable() != SUCCESS )
|
||||
{
|
||||
hb_errRT_DBCMD( EG_ARG, EDBCMD_BADPARAMETER, NULL, HB_ERR_FUNCNAME );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( szAlias )
|
||||
{
|
||||
pSymAlias = hb_dynsymFindName( szAlias );
|
||||
|
||||
/* verify if the alias name is valid symbol */
|
||||
if( hb_rddVerifyAliasName( szAlias ) != SUCCESS )
|
||||
{
|
||||
hb_errRT_DBCMD_Ext( EG_BADALIAS, EDBCMD_BADALIAS, NULL, szAlias, EF_CANDEFAULT );
|
||||
return NULL;
|
||||
}
|
||||
/* verify if the alias is already in use */
|
||||
if( hb_dynsymAreaHandle( pSymAlias ) != 0 )
|
||||
{
|
||||
hb_errRT_DBCMD_Ext( EG_DUPALIAS, EDBCMD_DUPALIAS, NULL, szAlias, EF_CANDEFAULT );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* protect by critical section access to s_pDetachedAreas array */
|
||||
hb_threadEnterCriticalSection( &s_waMtx );
|
||||
for( ;; )
|
||||
{
|
||||
if( s_pDetachedAreas )
|
||||
{
|
||||
ULONG ulLen = hb_arrayLen( s_pDetachedAreas ), ulPos = 1;
|
||||
if( pSymAlias )
|
||||
{
|
||||
for( ulPos = 1; ulPos <= ulLen; ++ulPos )
|
||||
{
|
||||
AREAP * pDetachedArea = ( AREAP * )
|
||||
hb_arrayGetPtr( hb_arrayGetItemPtr( s_pDetachedAreas, ulPos ), 1 );
|
||||
if( pSymAlias == ( PHB_DYNS ) ( *pDetachedArea )->atomAlias )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ulPos <= ulLen )
|
||||
{
|
||||
PHB_ITEM pArray = hb_arrayGetItemPtr( s_pDetachedAreas, ulPos );
|
||||
AREAP * pDetachedArea = ( AREAP * ) hb_arrayGetPtr( pArray, 1 );
|
||||
|
||||
pArea = *pDetachedArea;
|
||||
*pDetachedArea = NULL;
|
||||
if( pCargo )
|
||||
hb_arrayGet( pArray, 2, pCargo );
|
||||
hb_arrayDel( s_pDetachedAreas, ulPos );
|
||||
hb_arraySize( s_pDetachedAreas, ulLen - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( pArea || !fWait )
|
||||
break;
|
||||
|
||||
hb_vmUnlock();
|
||||
/* wait for detached workareas */
|
||||
hb_threadCondWait( &s_waCond, &s_waMtx );
|
||||
hb_vmLock();
|
||||
if( hb_vmRequestQuery() != 0 )
|
||||
break;
|
||||
}
|
||||
/* leave critical section */
|
||||
hb_threadLeaveCriticalSection( &s_waMtx );
|
||||
|
||||
/* atach WA and set alias */
|
||||
if( pArea )
|
||||
hb_waNodeInsert( hb_stackRDD(), pArea );
|
||||
|
||||
return pArea;
|
||||
}
|
||||
|
||||
@@ -1133,3 +1133,48 @@ ERRCODE hb_rddTransRecords( AREAP pArea,
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
static ERRCODE hb_rddCloseParentRel( AREAP pArea, void * pChildArea )
|
||||
{
|
||||
if( pArea->lpdbRelations )
|
||||
{
|
||||
LPDBRELINFO * lpdbRelationPtr = &pArea->lpdbRelations;
|
||||
USHORT uiArea = ( ( AREAP ) pChildArea )->uiArea;
|
||||
|
||||
do
|
||||
{
|
||||
LPDBRELINFO lpdbRelation = *lpdbRelationPtr;
|
||||
|
||||
if( lpdbRelation->lpaChild->uiArea == uiArea )
|
||||
{
|
||||
/* Clear this relation */
|
||||
hb_rddSelectWorkAreaNumber( lpdbRelation->lpaChild->uiArea );
|
||||
SELF_CHILDEND( lpdbRelation->lpaChild, lpdbRelation );
|
||||
if( lpdbRelation->itmCobExpr )
|
||||
hb_itemRelease( lpdbRelation->itmCobExpr );
|
||||
if( lpdbRelation->abKey )
|
||||
hb_itemRelease( lpdbRelation->abKey );
|
||||
|
||||
*lpdbRelationPtr = lpdbRelation->lpdbriNext;
|
||||
hb_xfree( lpdbRelation );
|
||||
}
|
||||
else
|
||||
lpdbRelationPtr = &lpdbRelation->lpdbriNext;
|
||||
}
|
||||
while ( *lpdbRelationPtr );
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* close all parent relations */
|
||||
ERRCODE hb_rddCloseAllParentRelations( AREAP pArea )
|
||||
{
|
||||
ERRCODE errCode = SUCCESS;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddCloseAllParentRelations(%p)", pArea));
|
||||
|
||||
if( pArea->uiParents > 0 )
|
||||
errCode = hb_rddIterateWorkAreas( hb_rddCloseParentRel, pArea );
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
@@ -655,52 +655,6 @@ static ERRCODE hb_waAlias( AREAP pArea, BYTE * szAlias )
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the table in the WorkArea - helper function
|
||||
*/
|
||||
static ERRCODE hb_waCloseAux( AREAP pArea, void * pChildArea )
|
||||
{
|
||||
USHORT uiPrevArea, uiArea;
|
||||
LPDBRELINFO lpdbRelation, lpdbRelPrev, lpdbRelTmp;
|
||||
|
||||
uiArea = ( ( AREAP ) pChildArea )->uiArea;
|
||||
if( pArea->lpdbRelations )
|
||||
{
|
||||
uiPrevArea = hb_rddGetCurrentWorkAreaNumber();
|
||||
lpdbRelation = pArea->lpdbRelations;
|
||||
lpdbRelPrev = NULL;
|
||||
while( lpdbRelation )
|
||||
{
|
||||
if( lpdbRelation->lpaChild->uiArea == uiArea )
|
||||
{
|
||||
/* Clear this relation */
|
||||
hb_rddSelectWorkAreaNumber( lpdbRelation->lpaChild->uiArea );
|
||||
SELF_CHILDEND( lpdbRelation->lpaChild, lpdbRelation );
|
||||
hb_rddSelectWorkAreaNumber( uiPrevArea );
|
||||
if( lpdbRelation->itmCobExpr )
|
||||
{
|
||||
hb_itemRelease( lpdbRelation->itmCobExpr );
|
||||
}
|
||||
if( lpdbRelation->abKey )
|
||||
hb_itemRelease( lpdbRelation->abKey );
|
||||
lpdbRelTmp = lpdbRelation;
|
||||
if( lpdbRelPrev )
|
||||
lpdbRelPrev->lpdbriNext = lpdbRelation->lpdbriNext;
|
||||
else
|
||||
pArea->lpdbRelations = lpdbRelation->lpdbriNext;
|
||||
lpdbRelation = lpdbRelation->lpdbriNext;
|
||||
hb_xfree( lpdbRelTmp );
|
||||
}
|
||||
else
|
||||
{
|
||||
lpdbRelPrev = lpdbRelation;
|
||||
lpdbRelation = lpdbRelation->lpdbriNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the table in the WorkArea.
|
||||
*/
|
||||
@@ -713,11 +667,8 @@ static ERRCODE hb_waClose( AREAP pArea )
|
||||
SELF_CLEARREL( pArea );
|
||||
SELF_CLEARLOCATE( pArea );
|
||||
|
||||
if( pArea->uiParents > 0 )
|
||||
{
|
||||
/* Clear relations that has this area as a child */
|
||||
hb_rddIterateWorkAreas( hb_waCloseAux, pArea );
|
||||
}
|
||||
/* Clear relations that has this area as a child */
|
||||
hb_rddCloseAllParentRelations( pArea );
|
||||
|
||||
if( pArea->atomAlias )
|
||||
hb_dynsymSetAreaHandle( ( PHB_DYNS ) pArea->atomAlias, 0 );
|
||||
@@ -2136,6 +2087,8 @@ HB_EXPORT void hb_rddShutDown( void )
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_rddShutDown()"));
|
||||
|
||||
hb_rddCloseDetachedAreas();
|
||||
|
||||
if( s_uiRddCount > 0 )
|
||||
{
|
||||
for( uiCount = 0; uiCount < s_uiRddCount; uiCount++ )
|
||||
|
||||
@@ -704,13 +704,13 @@ HB_EXPORT void hb_vmThreadQuit( void )
|
||||
|
||||
if( HB_IS_BYREF( pReturn ) )
|
||||
pReturn = hb_itemUnRef( pReturn );
|
||||
if( !pState->pResult )
|
||||
pState->pResult = hb_itemNew( NULL );
|
||||
|
||||
hb_itemMove( pState->pResult, pReturn );
|
||||
if( !pState->pResult )
|
||||
pState->pResult = hb_itemNew( pReturn );
|
||||
else
|
||||
hb_itemCopy( pState->pResult, pReturn );
|
||||
}
|
||||
else
|
||||
hb_itemClear( hb_stackReturnItem() );
|
||||
hb_itemClear( hb_stackReturnItem() );
|
||||
|
||||
hb_rddCloseAll(); /* close all workareas */
|
||||
hb_stackRemove( 1 ); /* clear stack items, leave only initial symbol item */
|
||||
|
||||
@@ -209,7 +209,7 @@ static HB_FHANDLE open_handle( PHB_SET_STRUCT pSet, const char * file_name, BOOL
|
||||
( hb_strnicmp( pFilename->szName, "COM", 3 ) == 0 &&
|
||||
pFilename->szName[3] >= '1' && pFilename->szName[3] <= '9' ) ) ) )
|
||||
{
|
||||
hb_strupr( pFilename->szName );
|
||||
hb_strupr( ( char * ) pFilename->szName );
|
||||
def_ext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +373,12 @@ BOOL hb_threadJoin( HB_THREAD_T th_id )
|
||||
}
|
||||
return FALSE;
|
||||
#elif defined( HB_OS_OS2 )
|
||||
return DosWaitThread( &th_id, DCWW_WAIT ) == NO_ERROR;
|
||||
APIRET rc = DosWaitThread( &th_id, DCWW_WAIT );
|
||||
/* TOFIX: ERROR_INVALID_THREADID is a hack for failing DosWaitThread()
|
||||
* when thread terminates before DosWaitThread() call.
|
||||
* OS2 users please check and fix this code if possible.
|
||||
*/
|
||||
return rc == NO_ERROR || rc == ERROR_INVALID_THREADID;
|
||||
#else
|
||||
{ int TODO_MT; }
|
||||
return FALSE;
|
||||
@@ -390,14 +395,8 @@ BOOL hb_threadDetach( HB_THREAD_T th_id )
|
||||
#elif defined( HB_OS_WIN_32 )
|
||||
return CloseHandle( th_id ) != 0;
|
||||
#elif defined( HB_OS_OS2 )
|
||||
/* TODO: I do not know clean method of running thread detaching
|
||||
* In OS/2.
|
||||
* After termination the HVM threads are detached automatically
|
||||
* by GC but it may not clean allocated OS resources if caller
|
||||
* does not keep thread pointer item alive and the cleanup code
|
||||
* will be executed by THIS thread.
|
||||
*/
|
||||
return DosWaitThread( &th_id, DCWW_NOWAIT ) == NO_ERROR;
|
||||
APIRET rc = DosWaitThread( &th_id, DCWW_NOWAIT );
|
||||
return rc == NO_ERROR || rc == ERROR_INVALID_THREADID;
|
||||
#else
|
||||
{ int TODO_MT; }
|
||||
return FALSE;
|
||||
@@ -505,7 +504,6 @@ static PHB_THREADSTATE hb_thParam( int iParam )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HB_FUNC( HB_THREADSTART )
|
||||
{
|
||||
PHB_ITEM pStart = hb_param( 1, HB_IT_ANY );
|
||||
@@ -562,10 +560,16 @@ HB_FUNC( HB_THREADJOIN )
|
||||
{
|
||||
BOOL fResult = FALSE;
|
||||
|
||||
if( pThread->th_id && hb_threadJoin( pThread->th_id ) )
|
||||
if( pThread->th_id )
|
||||
{
|
||||
hb_vmUnlock();
|
||||
fResult = hb_threadJoin( pThread->th_id );
|
||||
if( fResult )
|
||||
pThread->th_id = 0;
|
||||
hb_vmLock();
|
||||
}
|
||||
if( fResult )
|
||||
{
|
||||
pThread->th_id = 0;
|
||||
fResult = TRUE;
|
||||
if( pThread->pResult )
|
||||
hb_itemParamStore( 2, pThread->pResult );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user