diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 90fac74389..699aba5875 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,30 @@ The license applies to all entries newer than 2009-04-28. */ +2011-03-08 09:44 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbvm.h + * harbour/src/vm/hvm.c + * added new public C function: + HB_BOOL hb_vmRequestReenterExt( void ); + hb_vmRequestReenterExt() checks if given thread has registered HVM + stack and if not it creates new one otherwise it makes the same + operations as hb_vmRequestReenter(). It should be also used with + hb_vmRequestRestore() which checks if new stack was allocated and + if yes then it releases it. + For ST HVM hb_vmRequestReenterExt() works exactly like + hb_vmRequestReenter(). + + * harbour/include/hbthread.h + ! typo in comment + + * harbour/contrib/hbwin/win_svc.c + ! fixed to work with MT HVM + + accept function symbol (@func()) as 2-nd parameter of + WIN_SERVICESTART() function + * replaced one HB_TCHAR_*() function by Harbour STR API one. + (for full UNICODE support we should eliminate all HB_TCHAR_*() + functions) + 2011-03-08 08:59 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * utils/hbmk2/hbmk2.prg * Invoke xhb compiler (in -xhb mode) for each input source file, diff --git a/harbour/contrib/hbwin/win_svc.c b/harbour/contrib/hbwin/win_svc.c index dd6d184624..f1604a29c6 100644 --- a/harbour/contrib/hbwin/win_svc.c +++ b/harbour/contrib/hbwin/win_svc.c @@ -53,6 +53,7 @@ #include "hbwapi.h" #include "hbvm.h" +#include "hbapiitm.h" #if ! defined( HB_OS_WIN_CE ) @@ -62,7 +63,7 @@ static SERVICE_STATUS s_ServiceStatus; static SERVICE_STATUS_HANDLE s_hStatus; -static char s_szHarbourEntryFunc[ HB_SYMBOL_NAME_LEN + 1 ]; +static PHB_SYMB s_sHarbourEntryFunc = NULL; static TCHAR s_lpServiceName[ 256 ]; /* Control handler function */ @@ -98,11 +99,9 @@ static VOID WINAPI hbwin_SvcMainFunction( DWORD dwArgc, LPTSTR * lpszArgv ) if( s_hStatus != ( SERVICE_STATUS_HANDLE ) 0 ) { - PHB_DYNS pDynSym = hb_dynsymFindName( s_szHarbourEntryFunc ); - - if( pDynSym ) + if( s_sHarbourEntryFunc != NULL ) { - if( hb_vmRequestReenter() ) + if( hb_vmRequestReenterExt() ) { DWORD i; int iArgCount = 0; @@ -111,7 +110,7 @@ static VOID WINAPI hbwin_SvcMainFunction( DWORD dwArgc, LPTSTR * lpszArgv ) s_ServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus( s_hStatus, &s_ServiceStatus ); - hb_vmPushSymbol( hb_dynsymSymbol( pDynSym ) ); + hb_vmPushSymbol( s_sHarbourEntryFunc ); hb_vmPushNil(); for( i = 1; i < dwArgc; ++i ) @@ -131,6 +130,10 @@ static VOID WINAPI hbwin_SvcMainFunction( DWORD dwArgc, LPTSTR * lpszArgv ) hb_vmRequestRestore(); } + else + { + HB_TRACE( HB_TR_DEBUG, ("HVM stack not available") ); + } } else { @@ -295,8 +298,14 @@ HB_FUNC( WIN_SERVICESTART ) SERVICE_TABLE_ENTRY lpServiceTable[ 2 ]; - HB_TCHAR_COPYTO( s_lpServiceName, hb_parcx( 1 ), HB_SIZEOFARRAY( s_lpServiceName ) - 1 ); - hb_strncpy( s_szHarbourEntryFunc, hb_parcx( 2 ), HB_SIZEOFARRAY( s_szHarbourEntryFunc ) - 1 ); + HB_ITEMCOPYSTR( hb_param( 1, HB_IT_STRING ), s_lpServiceName, HB_SIZEOFARRAY( s_lpServiceName ) ); + s_sHarbourEntryFunc = hb_itemGetSymbol( hb_param( 2, HB_IT_SYMBOL ) ); + if( s_sHarbourEntryFunc == NULL && HB_ISCHAR( 2 ) ) + { + PHB_DYNS pDynSym = hb_dynsymFindName( hb_parc( 2 ) ); + if( pDynSym && hb_dynsymIsFunction( pDynSym ) ) + s_sHarbourEntryFunc = hb_dynsymSymbol( pDynSym ); + } lpServiceTable[ 0 ].lpServiceName = s_lpServiceName; lpServiceTable[ 0 ].lpServiceProc = ( LPSERVICE_MAIN_FUNCTION ) hbwin_SvcMainFunction; diff --git a/harbour/include/hbthread.h b/harbour/include/hbthread.h index 1012d72ed2..adff715f72 100644 --- a/harbour/include/hbthread.h +++ b/harbour/include/hbthread.h @@ -374,7 +374,7 @@ extern HB_EXPORT void hb_threadReleaseCPU( void ); extern HB_EXPORT void hb_atomic_set( volatile HB_COUNTER * pCounter, HB_COUNTER value ); extern HB_EXPORT HB_COUNTER hb_atomic_get( volatile HB_COUNTER * pCounter ); extern HB_EXPORT void hb_atomic_inc( volatile HB_COUNTER * pCounter ); -extern HB_EXPORT HB_BOOL hb_atomic_dec( volatile HB_COUNTER * pCounter ); /* returns HB_TRUE when counter reach after decrementation */ +extern HB_EXPORT HB_BOOL hb_atomic_dec( volatile HB_COUNTER * pCounter ); /* returns HB_TRUE when counter reaches 0 after decrementation */ /* Critical sections or fast non recursive MUTEXes */ extern HB_EXPORT void hb_threadEnterCriticalSection( HB_CRITICAL_T * critical ); diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index 5cee7a7397..833144d2ab 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -129,12 +129,17 @@ extern HB_EXPORT void hb_vmRequestEndProc( void ); extern HB_EXPORT HB_USHORT hb_vmRequestQuery( void ); extern HB_EXPORT HB_BOOL hb_vmRequestReenter( void ); extern HB_EXPORT void hb_vmRequestRestore( void ); +extern HB_EXPORT HB_BOOL hb_vmRequestReenterExt( void ); + extern HB_EXPORT HB_BOOL hb_vmIsActive( void ); /* Return values of hb_vmRequestQuery() */ -#define HB_QUIT_REQUESTED 1 /* immediately quit the application */ -#define HB_BREAK_REQUESTED 2 /* break to nearest RECOVER/END sequence */ -#define HB_ENDPROC_REQUESTED 4 /* immediately return from procedure (error handler in macro evaluation) */ +#define HB_QUIT_REQUESTED 1 /* immediately quit the application */ +#define HB_BREAK_REQUESTED 2 /* break to nearest RECOVER/END sequence */ +#define HB_ENDPROC_REQUESTED 4 /* immediately return from procedure (error handler in macro evaluation) */ +#ifdef _HB_API_INTERNAL_ +#define HB_VMSTACK_REQUESTED 0x100 /* inetrnel flag to signal thread local stack */ +#endif /* Public PCode functions */ diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 6409a44cea..7893881476 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -8693,17 +8693,53 @@ void hb_vmRequestRestore( void ) uiAction = ( HB_USHORT ) hb_stackItemFromTop( -1 )->item.asInteger.value | hb_stackGetActionRequest(); - if( uiAction & HB_QUIT_REQUESTED ) - hb_stackSetActionRequest( HB_QUIT_REQUESTED ); - else if( uiAction & HB_BREAK_REQUESTED ) - hb_stackSetActionRequest( HB_BREAK_REQUESTED ); - else if( uiAction & HB_ENDPROC_REQUESTED ) - hb_stackSetActionRequest( HB_ENDPROC_REQUESTED ); - else - hb_stackSetActionRequest( 0 ); - hb_stackDec(); - hb_stackPopReturn(); +#if defined( HB_MT_VM ) + if( uiAction & HB_VMSTACK_REQUESTED ) + hb_vmThreadQuit(); + else +#endif + { + if( uiAction & HB_QUIT_REQUESTED ) + hb_stackSetActionRequest( HB_QUIT_REQUESTED ); + else if( uiAction & HB_BREAK_REQUESTED ) + hb_stackSetActionRequest( HB_BREAK_REQUESTED ); + else if( uiAction & HB_ENDPROC_REQUESTED ) + hb_stackSetActionRequest( HB_ENDPROC_REQUESTED ); + else + hb_stackSetActionRequest( 0 ); + + hb_stackDec(); + hb_stackPopReturn(); + } +} + +HB_BOOL hb_vmRequestReenterExt( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmRequestReenterExt()")); + + if( !s_fHVMActive ) + return HB_FALSE; + +#if defined( HB_MT_VM ) + { + HB_STACK_TLS_PRELOAD + HB_USHORT uiAction = hb_stackId() == NULL ? HB_VMSTACK_REQUESTED : 0; + + if( uiAction ) + hb_vmThreadInit( NULL ); + else + hb_stackPushReturn(); + + hb_vmPushInteger( uiAction | hb_stackGetActionRequest() ); + } +#else + hb_stackPushReturn(); + hb_vmPushInteger( hb_stackGetActionRequest() ); + hb_stackSetActionRequest( 0 ); +#endif + + return HB_TRUE; } HB_BOOL hb_vmIsActive( void )