diff --git a/ChangeLog.txt b/ChangeLog.txt index a8231532fb..9fb0037e11 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,13 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2015-09-15 14:58 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbvmpub.h + * src/vm/hvm.c + + added support for hb_vmAtInit(), hb_vmAtExit() and hb_vmAtQuit() + functions for dynamically loaded libraries + This modification should also fix issue #33 + 2015-09-14 19:30 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rtl/hbproces.c * use pipes instead of temporary files in OS2 builds of hb_fsProcessRun() diff --git a/include/hbvmpub.h b/include/hbvmpub.h index 298092af7e..765b8ec09a 100644 --- a/include/hbvmpub.h +++ b/include/hbvmpub.h @@ -219,12 +219,13 @@ typedef HB_CARGO_FUNC( ( * PHB_CARGO_FUNC ) ); typedef void * ( * PHB_ALLOCUPDT_FUNC )( void *, int ); -typedef void (*HB_INIT_FUNC)(void *); +typedef void ( * HB_INIT_FUNC )( void * ); /* List of functions used by hb_vmAtInit()/hb_vmAtExit() */ typedef struct _HB_FUNC_LIST { HB_INIT_FUNC pFunc; void * cargo; + void * hDynLib; struct _HB_FUNC_LIST * pNext; } HB_FUNC_LIST, * PHB_FUNC_LIST; diff --git a/src/vm/hvm.c b/src/vm/hvm.c index c79d01f499..4b8a8f8bfc 100644 --- a/src/vm/hvm.c +++ b/src/vm/hvm.c @@ -326,17 +326,46 @@ static void hb_vmAddModuleFunction( PHB_FUNC_LIST * pLstPtr, HB_INIT_FUNC pFunc, pLst->pFunc = pFunc; pLst->cargo = cargo; + pLst->hDynLib = s_hDynLibID; HB_ATINIT_LOCK(); pLst->pNext = *pLstPtr; *pLstPtr = pLst; HB_ATINIT_UNLOCK(); } -static void hb_vmDoModuleFunctions( PHB_FUNC_LIST pLst ) +static void hb_vmDoModuleFunctions( PHB_FUNC_LIST * pLstPtr ) +{ + while( *pLstPtr ) + { + PHB_FUNC_LIST pLst = *pLstPtr; + *pLstPtr = pLst->pNext; + pLst->pFunc( pLst->cargo ); + hb_xfree( pLst ); + } +} + +static void hb_vmDoModuleLibFunctions( PHB_FUNC_LIST * pLstPtr, void * hDynLib ) +{ + while( *pLstPtr ) + { + PHB_FUNC_LIST pLst = *pLstPtr; + if( pLst->hDynLib == hDynLib ) + { + *pLstPtr = pLst->pNext; + pLst->pFunc( pLst->cargo ); + hb_xfree( pLst ); + } + else + pLstPtr = &pLst->pNext; + } +} + +static void hb_vmDoModuleSetLibID( PHB_FUNC_LIST pLst, void * hDynLib, void * hNewDynLib ) { while( pLst ) { - pLst->pFunc( pLst->cargo ); + if( pLst->hDynLib == hDynLib ) + pLst->hDynLib = hNewDynLib; pLst = pLst->pNext; } } @@ -382,17 +411,17 @@ void hb_vmAtQuit( HB_INIT_FUNC pFunc, void * cargo ) static void hb_vmDoModuleInitFunctions( void ) { - hb_vmDoModuleFunctions( s_InitFunctions ); + hb_vmDoModuleFunctions( &s_InitFunctions ); } static void hb_vmDoModuleExitFunctions( void ) { - hb_vmDoModuleFunctions( s_ExitFunctions ); + hb_vmDoModuleFunctions( &s_ExitFunctions ); } static void hb_vmDoModuleQuitFunctions( void ) { - hb_vmDoModuleFunctions( s_QuitFunctions ); + hb_vmDoModuleFunctions( &s_QuitFunctions ); } @@ -7811,6 +7840,14 @@ void hb_vmInitSymbolGroup( void * hNewDynLib, int argc, const char * argv[] ) pLastSymbols = pLastSymbols->pNext; } + /* library symbols are modified beforeinit functions + execution intentionally because init functions may + load new modules [druzus] */ + hb_vmDoModuleSetLibID( s_InitFunctions, hDynLib, hNewDynLib ); + hb_vmDoModuleSetLibID( s_ExitFunctions, hDynLib, hNewDynLib ); + hb_vmDoModuleSetLibID( s_QuitFunctions, hDynLib, hNewDynLib ); + hb_vmDoModuleLibFunctions( &s_InitFunctions, hNewDynLib ); + if( fFound ) { HB_BOOL fClipInit = HB_TRUE; @@ -7889,15 +7926,16 @@ void hb_vmExitSymbolGroup( void * hDynLib ) pLastSymbols = pLastSymbols->pNext; } + hb_vmDoModuleLibFunctions( &s_ExitFunctions, hDynLib ); + hb_vmDoModuleLibFunctions( &s_QuitFunctions, hDynLib ); + if( fFound ) { pLastSymbols = s_pSymbols; while( pLastSymbols ) { if( pLastSymbols->hDynLib == hDynLib ) - { hb_vmFreeSymbols( pLastSymbols ); - } pLastSymbols = pLastSymbols->pNext; } }