2009-12-11 04:13 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbapiitm.h
  * harbour/src/vm/classes.c
    * added new internal HVM macro

  * harbour/src/vm/thread.c
    + added new function
         hb_threadOnceInit( @<item> <value> ) -> <lInitialized>
      It assigns <value> to <item> if <item> is NIL in MT safe way so it's
      assigned only once. It's reduced but faster version of hb_threadOnce()

  * harbour/include/hbapicdp.h
    * define HB_WCHAR as wchar_t on Windows platforms for compilers which
      refuse to make conversions between types using the same base type.

  * harbour/contrib/hbwin/win_dll.c
    * code cleanup
This commit is contained in:
Przemyslaw Czerpak
2009-12-11 03:13:24 +00:00
parent 114db78988
commit 12dc010686
6 changed files with 122 additions and 75 deletions

View File

@@ -17,6 +17,24 @@
past entries belonging to author(s): Viktor Szakats.
*/
2009-12-11 04:13 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapiitm.h
* harbour/src/vm/classes.c
* added new internal HVM macro
* harbour/src/vm/thread.c
+ added new function
hb_threadOnceInit( @<item> <value> ) -> <lInitialized>
It assigns <value> to <item> if <item> is NIL in MT safe way so it's
assigned only once. It's reduced but faster version of hb_threadOnce()
* harbour/include/hbapicdp.h
* define HB_WCHAR as wchar_t on Windows platforms for compilers which
refuse to make conversions between types using the same base type.
* harbour/contrib/hbwin/win_dll.c
* code cleanup
2009-12-11 00:20 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
+ contrib/hbqt/hbqt_hbdbfmodel.h
+ Missed from prev commits.

View File

@@ -66,7 +66,7 @@
#include "hbapiitm.h"
#include "hbwinuni.h"
#if !defined( HB_NO_ASM ) && defined( HB_OS_WIN ) && !defined( __CYGWIN__ )
#if defined( HB_OS_WIN ) && !defined( __CYGWIN__ ) && !defined( HB_NO_ASM )
/* ==================================================================
* DynaCall support comments below
@@ -378,16 +378,12 @@ RESULT DynaCall( int iFlags, LPVOID lpFunction, int nArgs,
typedef struct _XPP_DLLEXEC
{
DWORD dwType; /* type info */
HMODULE hDLL; /* Handle */
char * cProc; /* function name */
WORD wOrdinal; /* function ordinal */
BOOL fFreeDLL; /* Free library handle on destroy? */
DWORD dwFlags; /* Calling Flags */
LPVOID lpFunc;
LPVOID lpFunc; /* Function Address */
} XPP_DLLEXEC, * PXPP_DLLEXEC;
#define _DLLEXEC_SIGNATURE 0x45584543
#define _DLLEXEC_MAXPARAM 15
/* Based originally on CallDLL() from What32 */
@@ -447,6 +443,7 @@ static void DllExec( int iFlags, int iRtype, LPVOID lpFunction, PXPP_DLLEXEC xec
case HB_IT_LONG:
case HB_IT_DATE:
case HB_IT_LOGICAL:
/* TOFIX: HB_IT_LONG is 64 bit integer */
Parm[ iCnt ].nWidth = sizeof( DWORD );
Parm[ iCnt ].numargs.dwArg = ( DWORD ) hb_itemGetNL( pParam );
@@ -490,12 +487,11 @@ static void DllExec( int iFlags, int iRtype, LPVOID lpFunction, PXPP_DLLEXEC xec
Parm[ iCnt ].dwFlags = DC_FLAG_ARGPTR; /* use the pointer */
break;
case HB_IT_ARRAY:
case HB_IT_HASH:
case HB_IT_SYMBOL:
case HB_IT_ALIAS:
case HB_IT_MEMOFLAG:
case HB_IT_BLOCK:
case HB_IT_MEMVAR:
default:
hb_errRT_BASE( EG_ARG, 2010, "Unknown parameter type to DLL function", HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
@@ -612,20 +608,14 @@ static void DllExec( int iFlags, int iRtype, LPVOID lpFunction, PXPP_DLLEXEC xec
/* ------------------------------------------------------------------ */
#if !defined( HB_OS_WIN_CE )
static HB_GARBAGE_FUNC( _DLLUnload )
{
PXPP_DLLEXEC xec = ( PXPP_DLLEXEC ) Cargo;
if( xec->dwType == _DLLEXEC_SIGNATURE )
if( xec->hDLL && xec->fFreeDLL )
{
if( xec->hDLL )
FreeLibrary( xec->hDLL );
if( xec->cProc )
hb_xfree( xec->cProc );
xec->dwType = 0;
FreeLibrary( xec->hDLL );
xec->hDLL = NULL;
}
}
@@ -636,17 +626,29 @@ static const HB_GC_FUNCS s_gcDllFuncs =
};
#endif
static LPVOID hb_getprocaddress( HMODULE hDLL, int iProc )
static LPVOID hb_getprocaddress( HMODULE hDLL, int iParam )
{
#if defined( HB_OS_WIN_CE )
HB_SYMBOL_UNUSED( hDLL );
HB_SYMBOL_UNUSED( iProc );
return NULL;
void * hStr;
ULONG ulLen;
LPCWSTR szProc = hb_parstr_u16( iParam, HB_CDP_ENDIAN_NATIVE, &hStr, &ulLen );
LPVOID lpFunction = ( LPVOID ) GetProcAddress( hDLL, szProc ? szProc :
( LPCWSTR ) ( HB_PTRDIFF ) ( hb_parni( iParam ) & 0x0FFFF ) );
if( ! lpFunction && szProc ) /* try with WIDE suffix? */
{
LPWSTR pszProcW = ( LPWSTR ) hb_xgrab( ( ulLen + 2 ) * sizeof( WCHAR ) );
memcpy( pszProcW, szProc, ulLen * sizeof( WCHAR ) );
pszProcW[ ulLen++ ] = L'W';
pszProcW[ ulLen++ ] = 0;
lpFunction = ( LPVOID ) GetProcAddress( hDLL, pszProcW );
hb_xfree( pszProcW );
}
hb_strfree( hStr );
#else
const char * szProc = hb_parc( iProc );
LPVOID lpFunction = ( LPVOID ) GetProcAddress( hDLL, szProc ? szProc : ( LPCSTR ) ( HB_PTRDIFF ) hb_parnint( iProc ) );
const char * szProc = hb_parc( iParam );
LPVOID lpFunction = ( LPVOID ) GetProcAddress( hDLL, szProc ? szProc :
( LPCSTR ) ( HB_PTRDIFF ) ( hb_parni( iParam ) & 0x0FFFF ) );
if( ! lpFunction && szProc ) /* try with ANSI suffix? */
{
@@ -654,16 +656,15 @@ static LPVOID hb_getprocaddress( HMODULE hDLL, int iProc )
lpFunction = ( LPVOID ) GetProcAddress( hDLL, pszFuncName );
hb_xfree( pszFuncName );
}
return lpFunction;
#endif
return lpFunction;
}
HB_FUNC( LOADLIBRARY )
{
void * hName;
hb_retnint( ( HB_PTRDIFF ) LoadLibrary( ( LPCTSTR ) HB_PARSTRDEF( 1, &hName, NULL ) ) );
hb_retnint( ( HB_PTRDIFF ) LoadLibrary( HB_PARSTRDEF( 1, &hName, NULL ) ) );
hb_strfree( hName );
}
@@ -687,7 +688,7 @@ HB_FUNC( GETPROCADDRESS )
else
hDLL = ( HMODULE ) hb_parptr( 1 );
hb_retptr( hDLL ? ( void * ) hb_getprocaddress( hDLL, 2 ) : NULL );
hb_retptr( hDLL ? hb_getprocaddress( hDLL, 2 ) : NULL );
}
#ifdef HB_COMPAT_XPP
@@ -704,16 +705,16 @@ HB_FUNC( DLLUNLOAD )
HB_FUNC( DLLCALL )
{
HMODULE hDLL;
HMODULE hDLL = NULL;
if( HB_ISPOINTER( 1 ) )
hDLL = ( HMODULE ) hb_parptr( 1 );
else if( HB_ISNUM( 1 ) )
hDLL = ( HMODULE ) ( HB_PTRDIFF ) hb_parnint( 1 );
else
else if( HB_ISCHAR( 1 ) )
{
void * hName;
hDLL = LoadLibrary( ( LPCTSTR ) HB_PARSTRDEF( 1, &hName, NULL ) );
hDLL = LoadLibrary( HB_PARSTR( 1, &hName, NULL ) );
hb_strfree( hName );
}
@@ -730,17 +731,18 @@ HB_FUNC( DLLCALL )
HB_FUNC( DLLPREPARECALL )
{
#if ! defined( HB_OS_WIN_CE )
PXPP_DLLEXEC xec = ( PXPP_DLLEXEC ) hb_gcAllocate( sizeof( XPP_DLLEXEC ), &s_gcDllFuncs );
char * pszErrorText;
const char * pszErrorText;
memset( xec, 0, sizeof( XPP_DLLEXEC ) );
if( HB_ISCHAR( 1 ) )
{
void * hName;
xec->hDLL = LoadLibrary( ( LPCTSTR ) HB_PARSTRDEF( 1, &hName, NULL ) );
xec->hDLL = LoadLibrary( HB_PARSTR( 1, &hName, NULL ) );
hb_strfree( hName );
if( xec->hDLL )
xec->fFreeDLL = TRUE;
}
else if( HB_ISPOINTER( 1 ) )
xec->hDLL = ( HMODULE ) hb_parptr( 1 );
@@ -749,53 +751,32 @@ HB_FUNC( DLLPREPARECALL )
if( xec->hDLL )
{
HB_SIZE ulLen = 0;
if( HB_ISCHAR( 3 ) )
{
ulLen = hb_parclen( 3 ) + 1;
xec->cProc = ( char * ) hb_xgrab( ulLen + 1 ); /* Reserving space for possible ANSI "A" suffix. */
hb_strncpy( xec->cProc, hb_parc( 3 ), ulLen );
}
else if( HB_ISNUM( 3 ) )
xec->wOrdinal = ( WORD ) hb_parni( 3 );
xec->lpFunc = ( LPVOID ) GetProcAddress( xec->hDLL, xec->cProc ? xec->cProc : ( LPCSTR ) ( HB_PTRDIFF ) xec->wOrdinal );
if( ! xec->lpFunc && xec->cProc ) /* try with ANSI suffix? */
xec->lpFunc = ( LPVOID ) GetProcAddress( xec->hDLL, hb_strncat( xec->cProc, "A", ulLen ) );
xec->lpFunc = hb_getprocaddress( xec->hDLL, 3 );
if( xec->lpFunc )
{
xec->dwType = _DLLEXEC_SIGNATURE;
xec->dwFlags = HB_ISNUM( 2 ) ? hb_parnl( 2 ) : DC_CALL_STD;
hb_retptrGC( xec );
return;
}
if( HB_ISCHAR( 1 ) )
FreeLibrary( xec->hDLL );
pszErrorText = HB_ISCHAR( 3 ) ? ( char * ) "Invalid function name" : ( char * ) "Invalid function ordinal";
pszErrorText = HB_ISCHAR( 3 ) ? "Invalid function name" : "Invalid function ordinal";
}
else
pszErrorText = HB_ISCHAR( 1 ) ? ( char * ) "Invalid library name" : ( char * ) "Invalid library handle";
pszErrorText = HB_ISCHAR( 1 ) ? "Invalid library name" : "Invalid library handle";
hb_gcFree( xec );
hb_errRT_BASE( EG_ARG, 2010, pszErrorText, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
#endif
}
HB_FUNC( DLLEXECUTECALL )
{
PXPP_DLLEXEC xec = ( PXPP_DLLEXEC ) hb_parptr( 1 );
PXPP_DLLEXEC xec = ( PXPP_DLLEXEC ) hb_parptrGC( &s_gcDllFuncs, 1 );
if( xec && xec->dwType == _DLLEXEC_SIGNATURE && xec->hDLL && xec->lpFunc )
if( xec && xec->hDLL && xec->lpFunc )
DllExec( 0, 0, NULL, xec, hb_pcount(), 2 );
}
#endif
#endif /* HB_COMPAT_XPP */
/* ------------------------------------------------------------------ */
@@ -816,4 +797,4 @@ HB_FUNC( CALLDLLTYPED )
DllExec( DC_CALL_STD, hb_parni( 2 ), ( LPVOID ) hb_parptr( 1 ), NULL, hb_pcount(), 3 );
}
#endif
#endif /* HB_OS_WIN && && !__CYGWIN__ !HB_NO_ASM */

View File

@@ -74,7 +74,11 @@ HB_EXTERN_BEGIN
hb_cdpRegister( &s_codepage ); \
HB_CALL_ON_STARTUP_END( hb_codepage_Init_##id )
typedef USHORT HB_WCHAR;
#if defined( HB_OS_WIN )
typedef wchar_t HB_WCHAR;
#else
typedef unsigned short HB_WCHAR;
#endif
typedef struct _HB_UNITABLE
{

View File

@@ -202,6 +202,18 @@ extern HB_EXPORT PHB_ITEM hb_itemDeserialize( const char ** pBufferPtr, ULON
# define hb_itemRawMove( dst, src ) hb_itemMove( (dst), (src) )
#endif
/* intentional low level hack to eliminate race condition in
* unprotected readonly access in few places in core code only.
* hb_item[Raw]Move() moves HB_ITEM structure members first coping
* 'type' and then 'item' parts of HB_ITEM. In this macro the order
* is reverted. [druzus]
*/
# define hb_itemSafeMove( dst, src ) do { \
(dst)->item = (src)->item; \
(dst)->type = (src)->type; \
(src)->type = HB_IT_NIL; \
} while( 0 )
#else
# define hb_itemSetNil( item ) hb_itemClear( (item) )

View File

@@ -4970,16 +4970,10 @@ HB_FUNC( __CLSUNLOCKDEF )
if( pClsDst && pClsSrc && HB_IS_NIL( pClsDst ) && ! HB_ISBYREF( 2 ) )
{
/* intentional low level hack to eliminate race condition in
* unprotected readonly access.
* hb_itemMove() uses memcpy() for whole HB_ITEM structure first
* coping 'type' and then 'item' parts of HB_ITEM so it cannot be
* used by us. [druzus]
/* special core code only macro used to eliminate race condition
* in unprotected readonly access to pClsDst variable.
*/
memcpy( &pClsDst->item, &pClsSrc->item, sizeof( pClsDst->item ) );
/* pClsDst->item.asArray.value = pClsSrc->item.asArray.value; */
pClsDst->type = pClsSrc->type;
pClsSrc->type = HB_IT_NIL;
hb_itemSafeMove( pClsDst, pClsSrc );
}
if( s_pClassMtx )

View File

@@ -1494,6 +1494,44 @@ HB_FUNC( HB_THREADONCE )
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_threadOnceInit( @<item> <value> ) -> <lInitialized>
* assign <value> to @<item> only if <item> is NIL
*/
HB_FUNC( HB_THREADONCEINIT )
{
PHB_ITEM pItem = hb_param( 1, HB_IT_ANY );
PHB_ITEM pValue = hb_param( 1, HB_IT_ANY );
if( pItem && pValue && HB_ISBYREF( 1 ) && !HB_ISBYREF( 2 ) )
{
BOOL fInitialized = FALSE;
if( HB_IS_NIL( pItem ) && !HB_IS_NIL( pValue ) )
{
#if defined( HB_MT_VM )
if( !s_fThreadInit )
hb_threadInit();
HB_CRITICAL_LOCK( s_once_mtx );
if( HB_IS_NIL( pItem ) )
{
/* special core code only macro used to eliminate race condition
* in unprotected readonly access to pItem variable.
*/
hb_itemSafeMove( pItem, pValue );
fInitialized = TRUE;
}
HB_CRITICAL_UNLOCK( s_once_mtx );
#else
hb_itemSafeMove( pItem, pValue );
fInitialized = TRUE;
#endif
}
hb_retl( fInitialized );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* II. MUTEXES */
typedef struct _HB_MUTEX