2008-09-22 03:49 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbstack.h
* harbour/source/vm/estack.c
* harbour/source/vm/hvm.c
+ added support for nested hb_vmUnlock()/hb_vmLock() calls
* harbour/source/rtl/hbinet.c
* encapsulated all potentially slow inet functions inside
hb_vmUnlock()/hb_vmLock() calls
This commit is contained in:
@@ -8,6 +8,16 @@
|
||||
2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
|
||||
*/
|
||||
|
||||
2008-09-22 03:49 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbstack.h
|
||||
* harbour/source/vm/estack.c
|
||||
* harbour/source/vm/hvm.c
|
||||
+ added support for nested hb_vmUnlock()/hb_vmLock() calls
|
||||
|
||||
* harbour/source/rtl/hbinet.c
|
||||
* encapsulated all potentially slow inet functions inside
|
||||
hb_vmUnlock()/hb_vmLock() calls
|
||||
|
||||
2008-09-22 02:34 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbvm.h
|
||||
* harbour/source/vm/hvm.c
|
||||
|
||||
@@ -161,7 +161,7 @@ typedef struct
|
||||
LONG lStatics; /* statics base for the current function call */
|
||||
LONG lWithObject; /* stack offset to base current WITH OBJECT item */
|
||||
LONG lRecoverBase; /* current SEQUENCE envelope offset or 0 if no SEQUENCE is active */
|
||||
USHORT uiActionRequest;/* Request for some action - stop processing of opcodes */
|
||||
USHORT uiActionRequest;/* request for some action - stop processing of opcodes */
|
||||
USHORT uiQuitState; /* HVM is quiting */
|
||||
HB_STACK_STATE state; /* first (default) stack state frame */
|
||||
HB_STACKRDD rdd; /* RDD related data */
|
||||
@@ -178,7 +178,8 @@ typedef struct
|
||||
HB_PRIVATE_STACK privates; /* private variables stack */
|
||||
HB_SET_STRUCT set;
|
||||
#if defined( HB_MT_VM )
|
||||
PHB_DYN_HANDLES pDynH; /* Dynamic symbol handles */
|
||||
int iUnlocked; /* counter for nested hb_vmUnlock() calls */
|
||||
PHB_DYN_HANDLES pDynH; /* dynamic symbol handles */
|
||||
int iDynH; /* number of dynamic symbol handles */
|
||||
void * pStackLst; /* this stack entry in stack linked list */
|
||||
HB_IOERRORS IOErrors; /* MT safe buffer for IO errors */
|
||||
@@ -277,6 +278,8 @@ extern void hb_stackIsStackRef( void *, PHB_TSD_FUNC );
|
||||
extern PHB_DYN_HANDLES hb_stackGetDynHandle( PHB_DYNS pDynSym );
|
||||
extern BOOL hb_stackQuitState( void );
|
||||
extern void hb_stackSetQuitState( USHORT uiState );
|
||||
extern int hb_stackUnlock( void );
|
||||
extern int hb_stackLock( void );
|
||||
#endif
|
||||
|
||||
#endif /* _HB_API_INTERNAL_ */
|
||||
@@ -319,6 +322,8 @@ extern void hb_stackIsStackRef( void *, PHB_TSD_FUNC );
|
||||
# define hb_stackListSet( p ) do { hb_stack.pStackLst = ( p ); } while ( 0 )
|
||||
# define hb_stackQuitState( ) ( hb_stack.uiQuitState != 0 )
|
||||
# define hb_stackSetQuitState( n ) do { hb_stack.uiQuitState = ( n ); } while( 0 )
|
||||
# define hb_stackUnlock() ( ++hb_stack.iUnlocked )
|
||||
# define hb_stackLock() ( --hb_stack.iUnlocked )
|
||||
#endif
|
||||
|
||||
#define hb_stackAllocItem( ) ( ( ++hb_stack.pPos == hb_stack.pEnd ? \
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "hbapi.h"
|
||||
#include "hbapiitm.h"
|
||||
#include "hbapierr.h"
|
||||
#include "hbvm.h"
|
||||
|
||||
/* Compile in Unix mode under Cygwin */
|
||||
#ifdef HB_OS_UNIX_COMPATIBLE
|
||||
@@ -224,12 +225,14 @@
|
||||
|
||||
#ifdef HB_OS_LINUX
|
||||
#include <signal.h>
|
||||
#define HB_INET_LINUX_INTERRUPT SIGUSR1+90
|
||||
/* #define HB_INET_LINUX_INTERRUPT SIGUSR1+90 */
|
||||
# ifdef HB_INET_LINUX_INTERRUPT
|
||||
static void hb_inetLinuxSigusrHandle( int sig )
|
||||
{
|
||||
/* nothing to do */
|
||||
HB_SYMBOL_UNUSED( sig );
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* JC1: we need it volatile to be minimally thread safe. */
|
||||
@@ -251,48 +254,54 @@ static int hb_selectReadSocket( HB_SOCKET_STRUCT *Socket )
|
||||
{
|
||||
fd_set set;
|
||||
struct timeval tv;
|
||||
int iResult;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET(Socket->com, &set);
|
||||
|
||||
if( Socket->timeout == -1 )
|
||||
{
|
||||
if( select( Socket->com + 1, &set, NULL, NULL, NULL ) < 0 )
|
||||
return 0;
|
||||
iResult = select( Socket->com + 1, &set, NULL, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
tv.tv_sec = Socket->timeout/ 1000;
|
||||
tv.tv_usec = (Socket->timeout % 1000) * 1000;
|
||||
if( select( Socket->com + 1, &set, NULL, NULL, &tv ) < 0 )
|
||||
return 0;
|
||||
iResult = select( Socket->com + 1, &set, NULL, NULL, &tv );
|
||||
}
|
||||
|
||||
return FD_ISSET( Socket->com, &set );
|
||||
hb_vmLock();
|
||||
|
||||
return iResult > 0 ? FD_ISSET( Socket->com, &set ) : 0;
|
||||
}
|
||||
|
||||
static int hb_selectWriteSocket( HB_SOCKET_STRUCT *Socket )
|
||||
{
|
||||
fd_set set;
|
||||
struct timeval tv;
|
||||
int iResult;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET(Socket->com, &set);
|
||||
|
||||
if( Socket->timeout == -1 )
|
||||
{
|
||||
if( select( Socket->com + 1, NULL, &set, NULL, NULL ) < 0 )
|
||||
return 0;
|
||||
iResult = select( Socket->com + 1, NULL, &set, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
tv.tv_sec = Socket->timeout/ 1000;
|
||||
tv.tv_usec = (Socket->timeout % 1000) * 1000;
|
||||
if( select( Socket->com + 1, NULL, &set, NULL, &tv ) < 0 )
|
||||
return 0;
|
||||
iResult = select( Socket->com + 1, NULL, &set, NULL, &tv );
|
||||
}
|
||||
|
||||
return FD_ISSET( Socket->com, &set );
|
||||
hb_vmLock();
|
||||
|
||||
return iResult > 0 ? FD_ISSET( Socket->com, &set ) : 0;
|
||||
}
|
||||
|
||||
#if defined(HB_OS_WIN_32)
|
||||
@@ -300,6 +309,9 @@ static int hb_selectWriteExceptSocket( HB_SOCKET_STRUCT *Socket )
|
||||
{
|
||||
fd_set set, eset;
|
||||
struct timeval tv;
|
||||
int iResult;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET(Socket->com, &set);
|
||||
@@ -308,27 +320,23 @@ static int hb_selectWriteExceptSocket( HB_SOCKET_STRUCT *Socket )
|
||||
|
||||
if( Socket->timeout == -1 )
|
||||
{
|
||||
if( select( Socket->com + 1, NULL, &set, &eset, NULL ) < 0 )
|
||||
return 2;
|
||||
iResult = select( Socket->com + 1, NULL, &set, &eset, NULL ) < 0 )
|
||||
}
|
||||
else
|
||||
{
|
||||
tv.tv_sec = Socket->timeout/ 1000;
|
||||
tv.tv_usec = (Socket->timeout % 1000) * 1000;
|
||||
if( select(Socket->com + 1, NULL, &set, &eset, &tv) < 0 )
|
||||
return 2;
|
||||
iResult = select(Socket->com + 1, NULL, &set, &eset, &tv);
|
||||
}
|
||||
|
||||
if( FD_ISSET( Socket->com, &eset) )
|
||||
{
|
||||
hb_vmLock();
|
||||
|
||||
if( iResult < 0 || FD_ISSET( Socket->com, &eset) )
|
||||
return 2;
|
||||
}
|
||||
|
||||
if( FD_ISSET( Socket->com, &set ) )
|
||||
{
|
||||
else if( FD_ISSET( Socket->com, &set ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -339,6 +347,8 @@ static struct hostent * hb_getHosts( char * name, HB_SOCKET_STRUCT *Socket )
|
||||
|
||||
/* TOFIX: make it MT safe */
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
/* let's see if name is an IP address; not necessary on Linux */
|
||||
#if defined(HB_OS_WIN_32) || defined(HB_OS_OS2)
|
||||
ULONG ulAddr;
|
||||
@@ -373,6 +383,9 @@ static struct hostent * hb_getHosts( char * name, HB_SOCKET_STRUCT *Socket )
|
||||
HB_SOCKET_SET_ERROR2( Socket, h_errno, (char *) hstrerror( h_errno ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
return Host;
|
||||
}
|
||||
|
||||
@@ -424,6 +437,8 @@ static int hb_socketConnect( HB_SOCKET_STRUCT *Socket )
|
||||
#endif
|
||||
int iOpt = 1;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
setsockopt( Socket->com, SOL_SOCKET, SO_KEEPALIVE, (const char *) &iOpt , sizeof( iOpt ));
|
||||
|
||||
/* we'll be using a nonblocking function */
|
||||
@@ -487,6 +502,8 @@ static int hb_socketConnect( HB_SOCKET_STRUCT *Socket )
|
||||
|
||||
hb_socketSetBlocking( Socket );
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
return Socket->errorCode == 0;
|
||||
}
|
||||
|
||||
@@ -532,7 +549,7 @@ HB_FUNC( HB_INETINIT )
|
||||
#define HB_MKWORD( l, h ) ((WORD)(((BYTE)(l)) | (((WORD)((BYTE)(h))) << 8)))
|
||||
WSADATA wsadata;
|
||||
WSAStartup( HB_MKWORD(1,1), &wsadata );
|
||||
#elif defined( HB_OS_LINUX )
|
||||
#elif defined( HB_INET_LINUX_INTERRUPT )
|
||||
signal( HB_INET_LINUX_INTERRUPT, hb_inetLinuxSigusrHandle );
|
||||
#endif
|
||||
s_iSessions = 1;
|
||||
@@ -572,6 +589,8 @@ HB_FUNC( HB_INETCLOSE )
|
||||
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
else if( Socket->com != ( HB_SOCKET_T ) -1 )
|
||||
{
|
||||
hb_vmUnlock();
|
||||
|
||||
#if defined( HB_OS_WIN_32 )
|
||||
shutdown( Socket->com, SD_BOTH );
|
||||
#elif defined(HB_OS_OS2)
|
||||
@@ -583,9 +602,11 @@ HB_FUNC( HB_INETCLOSE )
|
||||
hb_retni( HB_INET_CLOSE( Socket->com ) );
|
||||
Socket->com = ( HB_SOCKET_T ) -1;
|
||||
|
||||
#ifdef HB_OS_LINUX
|
||||
#ifdef HB_INET_LINUX_INTERRUPT
|
||||
kill( 0, HB_INET_LINUX_INTERRUPT );
|
||||
#endif
|
||||
|
||||
hb_vmLock();
|
||||
}
|
||||
else
|
||||
hb_retni( -1 );
|
||||
@@ -913,6 +934,8 @@ static void s_inetRecvInternal( int iMode )
|
||||
iMaxLen = iLen;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
iReceived = 0;
|
||||
iTimeElapsed = 0;
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
@@ -934,6 +957,8 @@ static void s_inetRecvInternal( int iMode )
|
||||
/* timed out; let's see if we have to run a cb routine */
|
||||
iTimeElapsed += Socket->timeout;
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
/* if we have a caPeriodic, timeLimit is our REAL timeout */
|
||||
if( Socket->caPeriodic )
|
||||
{
|
||||
@@ -956,12 +981,16 @@ static void s_inetRecvInternal( int iMode )
|
||||
hb_retni( iReceived );
|
||||
return;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
}
|
||||
}
|
||||
while( iReceived < iMaxLen && iLen > 0 );
|
||||
|
||||
Socket->count = iReceived;
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
if( iLen == 0 )
|
||||
{
|
||||
HB_SOCKET_SET_ERROR2( Socket, -2, "Connection closed" );
|
||||
@@ -1030,6 +1059,8 @@ static void s_inetRecvPattern( const char *szPattern )
|
||||
iMax = 0;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
Buffer = (char *) hb_xgrab( iBufferSize );
|
||||
@@ -1053,9 +1084,15 @@ static void s_inetRecvPattern( const char *szPattern )
|
||||
|
||||
if( Socket->caPeriodic )
|
||||
{
|
||||
BOOL fResult;
|
||||
|
||||
hb_vmLock();
|
||||
hb_execFromArray( Socket->caPeriodic );
|
||||
fResult = hb_parl( -1 );
|
||||
hb_vmUnlock();
|
||||
|
||||
/* do we continue? */
|
||||
if( hb_parl( -1 ) &&
|
||||
if( fResult &&
|
||||
( Socket->timelimit == -1 || iTimeElapsed < Socket->timelimit ) )
|
||||
{
|
||||
continue;
|
||||
@@ -1083,6 +1120,8 @@ static void s_inetRecvPattern( const char *szPattern )
|
||||
}
|
||||
while( iMax == 0 || iPos < iMax );
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
if( iLen <= 0 )
|
||||
{
|
||||
if( pResult )
|
||||
@@ -1216,6 +1255,8 @@ HB_FUNC( HB_INETRECVENDBLOCK )
|
||||
iBufferSize = pBufferSize ? hb_itemGetNI( pBufferSize ) : 80;
|
||||
iMax = pMaxSize ? hb_itemGetNI( pMaxSize ) : 0;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
Buffer = (char *) hb_xgrab( iBufferSize );
|
||||
@@ -1240,9 +1281,14 @@ HB_FUNC( HB_INETRECVENDBLOCK )
|
||||
iTimeElapsed += Socket->timeout;
|
||||
if( Socket->caPeriodic )
|
||||
{
|
||||
hb_execFromArray( Socket->caPeriodic );
|
||||
BOOL fResult;
|
||||
|
||||
if( hb_parl( -1 ) &&
|
||||
hb_vmLock();
|
||||
hb_execFromArray( Socket->caPeriodic );
|
||||
fResult = hb_parl( -1 );
|
||||
hb_vmUnlock();
|
||||
|
||||
if( fResult &&
|
||||
( Socket->timelimit == -1 || iTimeElapsed < Socket->timelimit ) )
|
||||
{
|
||||
continue;
|
||||
@@ -1259,12 +1305,12 @@ HB_FUNC( HB_INETRECVENDBLOCK )
|
||||
|
||||
for( protos = 0; protos < iprotos; protos++ )
|
||||
{
|
||||
if( cChar == Proto[protos][iprotosize[protos]-1] && iprotosize[protos] <= iPos )
|
||||
if( cChar == Proto[protos][iprotosize[protos] - 1] && iprotosize[protos] <= iPos )
|
||||
{
|
||||
bProtoFound = 1;
|
||||
for(iPosProto=0; iPosProto < (iprotosize[protos]-1); iPosProto++)
|
||||
for( iPosProto = 0; iPosProto < ( iprotosize[protos] - 1 ); iPosProto++ )
|
||||
{
|
||||
if(Proto[protos][iPosProto] != Buffer[ (iPos-iprotosize[protos])+iPosProto+1 ])
|
||||
if( Proto[protos][iPosProto] != Buffer[ ( iPos - iprotosize[protos] ) + iPosProto + 1 ] )
|
||||
{
|
||||
bProtoFound = 0;
|
||||
break;
|
||||
@@ -1277,21 +1323,18 @@ HB_FUNC( HB_INETRECVENDBLOCK )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bProtoFound)
|
||||
{
|
||||
if( bProtoFound )
|
||||
break;
|
||||
}
|
||||
|
||||
Buffer[ iPos++ ] = cChar;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while( iMax == 0 || iPos < iMax );
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
if( iLen <= 0 )
|
||||
{
|
||||
if( pResult )
|
||||
@@ -1364,16 +1407,17 @@ HB_FUNC( HB_INETDATAREADY )
|
||||
return;
|
||||
}
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
/* Watch our socket. */
|
||||
if( hb_pcount() > 1 )
|
||||
if( ISNUM( 1 ) )
|
||||
{
|
||||
iVal = hb_parni( 2 );
|
||||
tv.tv_sec = iVal / 1000;
|
||||
tv.tv_usec = (iVal % 1000) * 1000;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(Socket->com, &rfds);
|
||||
|
||||
@@ -1385,6 +1429,8 @@ HB_FUNC( HB_INETDATAREADY )
|
||||
HB_SOCKET_SET_ERROR( Socket );
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
hb_retni( iVal );
|
||||
}
|
||||
|
||||
@@ -1416,6 +1462,8 @@ static void s_inetSendInternal( int iMode )
|
||||
iSend = iLen;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
iSent = 0;
|
||||
@@ -1446,6 +1494,8 @@ static void s_inetSendInternal( int iMode )
|
||||
|
||||
Socket->count = iSent;
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
hb_retni( iLen > 0 ? iSent : -1 );
|
||||
}
|
||||
|
||||
@@ -1606,6 +1656,8 @@ HB_FUNC( HB_INETSERVER )
|
||||
|
||||
iListen = ISNUM( 3 ) ? hb_parni( 3 ) : 10;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
if( bind( Socket->com, (struct sockaddr *) &Socket->remote, sizeof(Socket->remote) ) )
|
||||
{
|
||||
HB_SOCKET_SET_ERROR( Socket );
|
||||
@@ -1619,6 +1671,8 @@ HB_FUNC( HB_INETSERVER )
|
||||
Socket->com = ( HB_SOCKET_T ) -1;
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
if( pSocket )
|
||||
hb_itemReturnRelease( pSocket );
|
||||
else
|
||||
@@ -1653,6 +1707,8 @@ HB_FUNC( HB_INETACCEPT )
|
||||
return;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
Len = sizeof( struct sockaddr_in );
|
||||
|
||||
/*
|
||||
@@ -1689,6 +1745,8 @@ HB_FUNC( HB_INETACCEPT )
|
||||
iError = -1;
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
if( iError == -1 )
|
||||
{
|
||||
HB_SOCKET_SET_ERROR2( Socket, -1, "Timeout" );
|
||||
@@ -1885,6 +1943,8 @@ HB_FUNC( HB_INETDGRAMBIND )
|
||||
szAddress = hb_parc( 2 );
|
||||
Socket->remote.sin_addr.s_addr = szAddress ? inet_addr( szAddress ) : INADDR_ANY;
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
if( bind( Socket->com, (struct sockaddr *) &Socket->remote, sizeof(Socket->remote) ) )
|
||||
{
|
||||
HB_SOCKET_SET_ERROR( Socket );
|
||||
@@ -1925,6 +1985,8 @@ HB_FUNC( HB_INETDGRAMBIND )
|
||||
}
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
hb_itemReturnRelease( pSocket );
|
||||
}
|
||||
|
||||
@@ -1998,6 +2060,8 @@ HB_FUNC( HB_INETDGRAMSEND )
|
||||
iLen = iMaxLen;
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
Socket->count = 0;
|
||||
@@ -2007,6 +2071,8 @@ HB_FUNC( HB_INETDGRAMSEND )
|
||||
(const struct sockaddr *) &Socket->remote, sizeof( Socket->remote ) );
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
hb_retni( Socket->count );
|
||||
|
||||
if( Socket->count == 0 )
|
||||
@@ -2060,6 +2126,8 @@ HB_FUNC( HB_INETDGRAMRECV )
|
||||
iMaxLen = ( int ) hb_itemGetCLen( pBuffer );
|
||||
}
|
||||
|
||||
hb_vmUnlock();
|
||||
|
||||
HB_SOCKET_ZERO_ERROR( Socket );
|
||||
|
||||
do
|
||||
@@ -2074,10 +2142,12 @@ HB_FUNC( HB_INETDGRAMRECV )
|
||||
iTimeElapsed += Socket->timeout;
|
||||
if( Socket->caPeriodic )
|
||||
{
|
||||
hb_vmLock();
|
||||
hb_execFromArray( Socket->caPeriodic );
|
||||
/* do we continue? */
|
||||
fRepeat = hb_parl( -1 ) &&
|
||||
( Socket->timelimit == -1 || iTimeElapsed < Socket->timelimit );
|
||||
hb_vmUnlock();
|
||||
}
|
||||
}
|
||||
while( fRepeat );
|
||||
@@ -2102,6 +2172,9 @@ HB_FUNC( HB_INETDGRAMRECV )
|
||||
{
|
||||
Socket->count = iLen;
|
||||
}
|
||||
|
||||
hb_vmLock();
|
||||
|
||||
hb_retni( iLen );
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,18 @@ void hb_stackSetQuitState( USHORT uiState )
|
||||
{
|
||||
hb_stack.uiQuitState = uiState;
|
||||
}
|
||||
|
||||
#undef hb_stackUnlock
|
||||
int hb_stackUnlock( void )
|
||||
{
|
||||
return ++hb_stack.iUnlocked;
|
||||
}
|
||||
|
||||
#undef hb_stackLock
|
||||
int hb_stackLock( void )
|
||||
{
|
||||
return --hb_stack.iUnlocked;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef hb_stackGetPrivateStack
|
||||
|
||||
@@ -433,52 +433,58 @@ static void hb_vmRequestTest( void )
|
||||
HB_VM_UNLOCK
|
||||
}
|
||||
|
||||
/* lock VM blocking GC execution by other threads */
|
||||
void hb_vmLock( void )
|
||||
{
|
||||
if( hb_stackId() ) /* check if thread has associated HVM stack */
|
||||
{
|
||||
HB_VM_LOCK
|
||||
while( TRUE )
|
||||
{
|
||||
if( hb_vmThreadRequest & HB_THREQUEST_QUIT )
|
||||
{
|
||||
if( !hb_stackQuitState() )
|
||||
{
|
||||
hb_stackSetQuitState( TRUE );
|
||||
hb_stackSetActionRequest( HB_QUIT_REQUESTED );
|
||||
}
|
||||
}
|
||||
if( hb_vmThreadRequest & HB_THREQUEST_STOP )
|
||||
hb_threadCondWait( &s_vmCond, &s_vmMtx );
|
||||
else
|
||||
break;
|
||||
}
|
||||
s_iRunningCount++;
|
||||
HB_VM_UNLOCK
|
||||
}
|
||||
}
|
||||
|
||||
/* unlock VM, allow GC execution */
|
||||
/* unlock VM, allow GC and other exclusive single task code execution */
|
||||
void hb_vmUnlock( void )
|
||||
{
|
||||
if( hb_stackId() ) /* check if thread has associated HVM stack */
|
||||
{
|
||||
HB_VM_LOCK
|
||||
s_iRunningCount--;
|
||||
if( hb_vmThreadRequest )
|
||||
if( hb_stackUnlock() == 1 )
|
||||
{
|
||||
if( hb_vmThreadRequest & HB_THREQUEST_QUIT )
|
||||
HB_VM_LOCK
|
||||
s_iRunningCount--;
|
||||
if( hb_vmThreadRequest )
|
||||
{
|
||||
if( !hb_stackQuitState() )
|
||||
if( hb_vmThreadRequest & HB_THREQUEST_QUIT )
|
||||
{
|
||||
hb_stackSetQuitState( TRUE );
|
||||
hb_stackSetActionRequest( HB_QUIT_REQUESTED );
|
||||
if( !hb_stackQuitState() )
|
||||
{
|
||||
hb_stackSetQuitState( TRUE );
|
||||
hb_stackSetActionRequest( HB_QUIT_REQUESTED );
|
||||
}
|
||||
}
|
||||
hb_threadCondBroadcast( &s_vmCond );
|
||||
}
|
||||
hb_threadCondBroadcast( &s_vmCond );
|
||||
HB_VM_UNLOCK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* lock VM blocking GC and other exclusive single task code execution */
|
||||
void hb_vmLock( void )
|
||||
{
|
||||
if( hb_stackId() ) /* check if thread has associated HVM stack */
|
||||
{
|
||||
if( hb_stackLock() == 0 )
|
||||
{
|
||||
HB_VM_LOCK
|
||||
while( TRUE )
|
||||
{
|
||||
if( hb_vmThreadRequest & HB_THREQUEST_QUIT )
|
||||
{
|
||||
if( !hb_stackQuitState() )
|
||||
{
|
||||
hb_stackSetQuitState( TRUE );
|
||||
hb_stackSetActionRequest( HB_QUIT_REQUESTED );
|
||||
}
|
||||
}
|
||||
if( hb_vmThreadRequest & HB_THREQUEST_STOP )
|
||||
hb_threadCondWait( &s_vmCond, &s_vmMtx );
|
||||
else
|
||||
break;
|
||||
}
|
||||
s_iRunningCount++;
|
||||
HB_VM_UNLOCK
|
||||
}
|
||||
HB_VM_UNLOCK
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user