diff --git a/ChangeLog.txt b/ChangeLog.txt index 177ab04e60..2a1799e2bc 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,84 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2017-04-14 16:36 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbapifs.h + * src/rtl/filesys.c + + added new C functions for UNIX and DJGPP builds: + int hb_fsPollFD( PHB_POLLFD pPollSet, int iCount, + HB_MAXINT nTimeOut ); + int hb_fsCanRead( HB_FHANDLE hFileHandle, HB_MAXINT nTimeOut ); + int hb_fsCanWrite( HB_FHANDLE hFileHandle, HB_MAXINT nTimeOut ); + These functions should be used instead of select() in C code to hide + low level access to select()/poll() functionality in *nix builds + (they are supported by DJGPP only to simplify existing code common + for DJGPP and *nix builds). Maximum file handle value which can be + used in select() is limited by FD_SETSIZE. Please note that it's + file handle value not number of file handles in the set. It creates + serious problem for applications which operate on great number of + handles (i.e. servers which have to keep open many sockets, pipes, + files, etc. for their clients) so the new file/socket/pipe/... + handle value can easy exceed FD_SETSIZE limit and in such case + cannot be used with select(). The modification on + 2016-04-05 21:24 UTC+0200 Przemyslaw Czerpak + resolved the problem only for sockets and pipes in code which uses + corresponding hb_socket*() and hb_fsPipe*() API but not for all + other cases. This one is for POSIX compilant code which needs pure + POSIX select()/poll() functionality. + Please note that HB_POLLFD structure should is compatible with + struct pollfd defined by POSIX.1-2001 anyhow not all platforms + confirm this standard so portable Harbour code should always use + HB_POLLFD and HB_POLL* constant values instead of POLL* ones. + + * include/hbdate.h + * src/common/hbdate.c + + added new C functions to calculate timeouts: + HB_MAXUINT hb_timerGet( void ); + HB_MAXUINT hb_timerInit( HB_MAXINT nTimeOut ); + HB_MAXINT hb_timerTest( HB_MAXINT nTimeOut, HB_MAXUINT * pnTimer ); + They are designed to be used instead of direct access to + hb_dateMilliSeconds(). Now they internally use hb_dateMilliSeconds() + but it can be easy replaced by any other system monotonic clock by + one local modification inside hb_timerGet() function. + + * src/rtl/filesys.c + * use hb_timer*() functions instead of hb_dateMilliSeconds() + * use hb_fsCanRead()/hb_fsCanWrite() instead of select()/poll() + It also fixed timeout processing inside hb_fsPipeIsData() and + hb_fsPipeWrite() in builds using poll() + + * src/rtl/filesys.c + * src/rtl/gtcrs/gtcrs.h + * src/rtl/gtcrs/gtcrs.c + * src/rtl/gtpca/gtpca.c + * src/rtl/gtsln/gtsln.c + * src/rtl/gtsln/mousesln.c + * src/rtl/gtstd/gtstd.c + * src/rtl/gttrm/gttrm.c + * src/rtl/gtxwc/gtxwc.c + * use hb_timer*() functions instead of hb_dateMilliSeconds() + * use hb_fsCanRead()/hb_fsCanWrite() instead of select()/poll() + + * src/vm/thread.c: + * src/rtl/gtwin/gtwin.c + * src/rtl/hbcom.c + * src/rtl/hbgtcore.c + * src/rtl/hblpp.c + * src/rtl/idle.c + * contrib/hbnetio/netiosrv.c: + * contrib/hbssl/ssl_sock.c: + * use hb_timer*() functions instead of hb_dateMilliSeconds() + + * contrib/xhb/hboutdbg.c + * use hb_fsCanWrite() instead of select() + + * src/rtl/hbsocket.c + ! repeat select() interrupted by signal inside hb_socketSelect() + when poll() function is not available + + * src/3rd/hbdossrl/serial.c + ! fixed -Wshift-negative-value GCC warnings + 2017-04-14 13:22 UTC+0200 Aleksander Czajczynski (hb fki.pl) * contrib/hbtip/ccgi.prg * contrib/hbtip/client.prg diff --git a/contrib/hbnetio/netiosrv.c b/contrib/hbnetio/netiosrv.c index 720e545f3f..d3b2e2ce44 100644 --- a/contrib/hbnetio/netiosrv.c +++ b/contrib/hbnetio/netiosrv.c @@ -348,26 +348,22 @@ static HB_BOOL s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lRead = 0, l; - HB_MAXUINT end_timer; - - end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; + HB_MAXINT timeout = conn->timeout; + HB_MAXUINT timer = hb_timerInit( timeout ); while( lRead < len && ! conn->stop ) { l = hb_sockexRead( conn->sock, ptr + lRead, len - lRead, 1000 ); - if( l <= 0 ) - { - if( l == 0 || - hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || - hb_vmRequestQuery() != 0 || - ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) - break; - } - else + if( l > 0 ) { lRead += l; conn->rd_count += l; } + else if( l == 0 || + hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || + ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; } return lRead == len; @@ -377,11 +373,11 @@ static HB_BOOL s_srvSendAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lSent = 0, l; - HB_MAXUINT end_timer; if( ! conn->mutex || hb_threadMutexLock( conn->mutex ) ) { - end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; + HB_MAXINT timeout = conn->timeout; + HB_MAXUINT timer = hb_timerInit( timeout ); while( lSent < len && ! conn->stop ) { @@ -391,13 +387,10 @@ static HB_BOOL s_srvSendAll( PHB_CONSRV conn, void * buffer, long len ) lSent += l; conn->wr_count += l; } - else - { - if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || - hb_vmRequestQuery() != 0 || - ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) - break; - } + else if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || + ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; } if( lSent == len && ! conn->stop ) { diff --git a/contrib/hbssl/ssl_sock.c b/contrib/hbssl/ssl_sock.c index 8027ccd73e..15e079d4aa 100644 --- a/contrib/hbssl/ssl_sock.c +++ b/contrib/hbssl/ssl_sock.c @@ -96,9 +96,9 @@ const char * hb_ssl_socketErrorStr( int iError ) long hb_ssl_socketRead( PHB_SSLSTREAM pStream, HB_SOCKET sd, void * buffer, long len, HB_MAXINT timeout ) { - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); long lRead = -1; int iToRead = -1; + HB_MAXUINT timer; /* sd = SSL_get_rfd( pStream->ssl ); */ @@ -117,6 +117,8 @@ long hb_ssl_socketRead( PHB_SSLSTREAM pStream, HB_SOCKET sd, pStream->blocking = !pStream->blocking; } + timer = hb_timerInit( timeout ); + if( len > 0 ) { iToRead = SSL_pending( pStream->ssl ); @@ -152,12 +154,8 @@ long hb_ssl_socketRead( PHB_SSLSTREAM pStream, HB_SOCKET sd, { if( timeout > 0 ) { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - timeout -= timecurr - timer; - if( timeout > 0 ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) != 0 ) { - timer = timecurr; if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else @@ -185,8 +183,8 @@ long hb_ssl_socketWrite( PHB_SSLSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_MAXINT timeout, long * plast ) { - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); long lWritten = 0, lWr = 0; + HB_MAXUINT timer; /* sd = SSL_get_wfd( pStream->ssl ); */ @@ -205,6 +203,8 @@ long hb_ssl_socketWrite( PHB_SSLSTREAM pStream, HB_SOCKET sd, pStream->blocking = !pStream->blocking; } + timer = hb_timerInit( timeout ); + while( len > 0 ) { lWr = SSL_write( pStream->ssl, buffer, ( int ) len ); @@ -230,12 +230,8 @@ long hb_ssl_socketWrite( PHB_SSLSTREAM pStream, HB_SOCKET sd, { if( timeout > 0 ) { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - timeout -= timecurr - timer; - if( timeout > 0 ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) != 0 ) { - timer = timecurr; if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else @@ -276,13 +272,11 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, HB_MAXINT timeout, PHB_ITEM pSSL, int * piResult ) { - int iResult; - PHB_SSLSTREAM pStream; HB_MAXUINT timer; + int iResult; pStream = ( HB_SSLSTREAM * ) hb_xgrabz( sizeof( HB_SSLSTREAM ) ); - timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); pStream->ssl = ssl; pStream->pSSL = pSSL ? hb_itemNew( pSSL ) : NULL; @@ -292,6 +286,9 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, SSL_set_mode( ssl, HB_SSL_MODE_AUTO_RETRY ); iResult = SSL_set_fd( ssl, sd ); + + timer = hb_timerInit( timeout ); + while( iResult == 1 ) { if( fServer ) @@ -312,16 +309,7 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, } else if( timeout > 0 ) { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout < 0 ) - timeout = 0; - timer = timecurr; - } - - if( timeout > 0 ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) != 0 ) { if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); diff --git a/contrib/xhb/hboutdbg.c b/contrib/xhb/hboutdbg.c index 343683aaaf..9f818a553f 100644 --- a/contrib/xhb/hboutdbg.c +++ b/contrib/xhb/hboutdbg.c @@ -191,20 +191,11 @@ void hb_OutDebug( const char * szMsg, HB_SIZE nMsgLen ) if( s_iDebugFd > 0 && HB_ISCHAR( 1 ) ) { - fd_set wrds; - struct timeval tv = { 0, 100000 }; /* wait each time a tenth of second */ - FD_ZERO( &wrds ); - FD_SET( s_iDebugFd, &wrds ); - - if( select( s_iDebugFd + 1, NULL, &wrds, NULL, &tv ) > 0 ) + if( hb_fsCanWrite( s_iDebugFd, 100 ) > 0 ) /* wait each time a tenth of second */ { if( ( HB_SIZE ) write( s_iDebugFd, szMsg, nMsgLen ) == nMsgLen ) { - tv.tv_sec = 0; - tv.tv_usec = 100000; - FD_ZERO( &wrds ); - FD_SET( s_iDebugFd, &wrds ); - if( select( s_iDebugFd + 1, NULL, &wrds, NULL, &tv ) > 0 ) + if( hb_fsCanWrite( s_iDebugFd, 100 ) > 0 ) { if( write( s_iDebugFd, "\n", 1 ) != 1 ) { diff --git a/include/hbapifs.h b/include/hbapifs.h index 993bd65f5b..f423ac8bbf 100644 --- a/include/hbapifs.h +++ b/include/hbapifs.h @@ -195,6 +195,31 @@ extern HB_EXPORT HB_BOOL hb_fsLink ( const char * pszExisting, const c extern HB_EXPORT HB_BOOL hb_fsLinkSym ( const char * pszTarget, const char * pszNewFile ); /* create symbolic (soft) link */ extern HB_EXPORT char * hb_fsLinkRead ( const char * pszFileName ); /* returns the link pointed to */ +#if defined( HB_OS_UNIX ) || defined( __DJGPP__ ) +/* for POSIX systems only, hides low level select()/poll() access, + intentionally covered by HB_OS_UNIX / __DJGPP__ macros to generate + compile time error in code which tries to use it on other platforms */ + +typedef struct +{ + HB_FHANDLE fd; + HB_SHORT events; + HB_SHORT revents; +} HB_POLLFD, * PHB_POLLFD; + +#define HB_POLLIN 0x0001 /* There is data to read */ +#define HB_POLLPRI 0x0002 /* There is urgent data to read */ +#define HB_POLLOUT 0x0004 /* Writing now will not block */ +#define HB_POLLERR 0x0008 /* Error condition */ +#define HB_POLLHUP 0x0010 /* Hung up */ +#define HB_POLLNVAL 0x0020 /* Invalid polling request */ + +extern HB_EXPORT int hb_fsPoll ( PHB_POLLFD pPollSet, int iCount, HB_MAXINT nTimeOut ); +extern HB_EXPORT int hb_fsCanRead ( HB_FHANDLE hFileHandle, HB_MAXINT nTimeOut ); +extern HB_EXPORT int hb_fsCanWrite ( HB_FHANDLE hFileHandle, HB_MAXINT nTimeOut ); +#endif /* HB_OS_UNIX */ + + #define hb_fsFLock( h, s, l ) hb_fsLock( h, s, l, FL_LOCK ) #define hb_fsFUnlock( h, s, l ) hb_fsLock( h, s, l, FL_UNLOCK ) diff --git a/include/hbdate.h b/include/hbdate.h index 5c3af6cb5e..798517313a 100644 --- a/include/hbdate.h +++ b/include/hbdate.h @@ -142,6 +142,10 @@ extern HB_EXPORT void hb_timeStampUnformat( const char * szDateTime, const char * szDateFormat, const char * szTimeFormat, long * plJulian, long * plMilliSec ); +extern HB_EXPORT HB_MAXUINT hb_timerGet( void ); +extern HB_EXPORT HB_MAXUINT hb_timerInit( HB_MAXINT nTimeOut ); +extern HB_EXPORT HB_MAXINT hb_timerTest( HB_MAXINT nTimeOut, HB_MAXUINT * pnTimer ); + HB_EXTERN_END #define HB_MINUTES_PER_DAY ( 24 * 60 ) diff --git a/src/3rd/hbdossrl/serial.c b/src/3rd/hbdossrl/serial.c index 09e30b0124..8f987e921c 100644 --- a/src/3rd/hbdossrl/serial.c +++ b/src/3rd/hbdossrl/serial.c @@ -88,7 +88,7 @@ */ #define SER_RX_BUFFER_SIZE (1L<rx_buff[(C)->rx_tail = ((C)->rx_tail+1) & SER_RX_BUFFER_SIZE_MASK] @@ -101,7 +101,7 @@ #define SER_RX_BUFFER_HIWATER(C) (SER_RX_BUFFER_CURRENT(C) > SER_RX_BUFFER_HIGH) #define SER_TX_BUFFER_SIZE (1L<tx_buff[(C)->tx_tail = ((C)->tx_tail+1) & SER_TX_BUFFER_SIZE_MASK] diff --git a/src/common/hbdate.c b/src/common/hbdate.c index bc016a2340..40e76200f4 100644 --- a/src/common/hbdate.c +++ b/src/common/hbdate.c @@ -1116,6 +1116,39 @@ double hb_timeLocalToUTC( double dTimeStamp ) iHour, iMinutes, iSeconds ) / HB_SECONDS_PER_DAY; } +HB_MAXUINT hb_timerGet( void ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_timerInit()" ) ); + + return hb_dateMilliSeconds(); +} + +HB_MAXUINT hb_timerInit( HB_MAXINT nTimeOut ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_timerInit(%" PFHL "d)", nTimeOut ) ); + + return nTimeOut > 0 ? hb_timerGet() : 0; +} + +HB_MAXINT hb_timerTest( HB_MAXINT nTimeOut, HB_MAXUINT * pnTimer ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_timerTest(%" PFHL "d, %p)", nTimeOut, pnTimer ) ); + + if( nTimeOut > 0 ) + { + HB_MAXUINT nTime = hb_timerGet(); + + if( nTime > *pnTimer ) + { + nTimeOut -= nTime - *pnTimer; + if( nTimeOut < 0 ) + nTimeOut = 0; + } + *pnTimer = nTime; + } + return nTimeOut; +} + #if defined( HB_OS_VXWORKS ) /* NOTE: This function is declared, but not present in diff --git a/src/harbour.def b/src/harbour.def index 086126c7ab..06c2702f1c 100644 --- a/src/harbour.def +++ b/src/harbour.def @@ -2541,6 +2541,7 @@ hb_fsPipeIsData hb_fsPipeRead hb_fsPipeUnblock hb_fsPipeWrite +hb_fsPoll hb_fsProcessClose hb_fsProcessOpen hb_fsProcessRun @@ -3452,6 +3453,9 @@ hb_timeStrGet hb_timeStrRawGet hb_timeUTCOffset hb_timeUnformat +hb_timerGet +hb_timerInit +hb_timerTest hb_tr_level hb_tr_stealth hb_tr_trace diff --git a/src/rtl/filesys.c b/src/rtl/filesys.c index 4cbf0470b0..fdcbc99d33 100644 --- a/src/rtl/filesys.c +++ b/src/rtl/filesys.c @@ -719,6 +719,331 @@ HB_FHANDLE hb_fsGetOsHandle( HB_FHANDLE hFileHandle ) #endif } +#if defined( HB_OS_UNIX ) || defined( __DJGPP__ ) +/* for POSIX systems only, hides low level select()/poll() access, + intentionally covered by HB_OS_UNIX macro to generate compile time + error in code which tries to use it on other platforms */ + +static int hb_fsCanAccess( HB_FHANDLE hFile, HB_MAXINT nTimeOut, HB_BOOL fRead ) +{ + int iResult; + + hb_vmUnlock(); + +#if defined( HB_HAS_POLL ) +{ + HB_MAXUINT timer = hb_timerInit( nTimeOut ); + struct pollfd fds; + short int events = fRead ? POLLIN : POLLOUT; + + fds.fd = hFile; + fds.events = events; + fds.revents = 0; + + for( ;; ) + { + HB_BOOL fLast = nTimeOut >= 0 && nTimeOut <= 1000; + int tout = fLast ? ( int ) nTimeOut : 1000; + + iResult = poll( &fds, 1, tout ); + hb_fsSetIOError( iResult >= 0, 0 ); + if( iResult > 0 && ( fds.revents & events ) == 0 ) + { + if( ( fds.revents & ( POLLHUP | POLLNVAL | POLLERR ) ) != 0 ) + { + iResult = -1; + break; + } + iResult = 0; + } + else if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR ) + { + iResult = 0; + fLast = HB_FALSE; + } + + if( iResult == 0 && ! fLast && hb_vmRequestQuery() == 0 && + ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) != 0 ) + continue; + + break; + } +} +#elif ! defined( HB_OS_SYMBIAN ) /* ! HB_HAS_POLL */ +{ +# if ! defined( HB_HAS_SELECT_TIMER ) + HB_MAXUINT timer = hb_timerInit( nTimeOut ); +# endif + + for( ;; ) + { + struct timeval tv; + fd_set fds; + + if( nTimeOut < 0 || nTimeOut >= 1000 ) + { + tv.tv_sec = 1; + tv.tv_usec = 0; + } + else + { + tv.tv_sec = ( long ) nTimeOut / 1000; + tv.tv_usec = ( long ) ( nTimeOut % 1000 ) * 1000; + } + + FD_ZERO( &fds ); + FD_SET( hFile, &fds ); + iResult = select( hFile + 1, fRead ? &fds : NULL, + fRead ? NULL : &fds, NULL, &tv ); + hb_fsSetIOError( iResult >= 0, 0 ); + + if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR ) + { + iResult = 0; +# if defined( HB_HAS_SELECT_TIMER ) + if( nTimeOut > 0 ) + nTimeOut += tv.tv_sec * 1000 + tv.tv_usec / 1000; +# endif + } +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult == 0 && nTimeOut > 0 ) + { + if( ( nTimeOut -= 1000 ) < 0 ) + break; + } + + if( iResult != 0 || nTimeOut == 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; +# endif + } +} +#else +{ + int iTODO; /* TODO: for given platform */ + + HB_SYMBOL_UNUSED( hFile ); + HB_SYMBOL_UNUSED( nTimeOut ); + HB_SYMBOL_UNUSED( fRead ); + iResult = -1; +} +#endif /* ! HB_HAS_POLL */ + + hb_vmLock(); + + return iResult; +} + +int hb_fsCanRead( HB_FHANDLE hFileHandle, HB_MAXINT nTimeOut ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_fsCanRead(%p, %" PFHL "d)", ( void * ) ( HB_PTRUINT ) hFileHandle, nTimeOut ) ); + + return hb_fsCanAccess( hFileHandle, nTimeOut, HB_TRUE ); +} + +int hb_fsCanWrite( HB_FHANDLE hFileHandle, HB_MAXINT nTimeOut ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_fsCanWrite(%p, %" PFHL "d)", ( void * ) ( HB_PTRUINT ) hFileHandle, nTimeOut ) ); + + return hb_fsCanAccess( hFileHandle, nTimeOut, HB_FALSE ); +} + +int hb_fsPoll( PHB_POLLFD pPollSet, int iCount, HB_MAXINT nTimeOut ) +{ + int iResult; + + HB_TRACE( HB_TR_DEBUG, ( "hb_fsPoll(%p, %d, %" PFHL "d)", pPollSet, iCount, nTimeOut ) ); + + hb_vmUnlock(); + +#if defined( HB_HAS_POLL ) +{ + struct pollfd fds[ 16 ], * pfds; + static const HB_BOOL s_fSamePoll = + sizeof( struct pollfd ) == sizeof( HB_POLLFD ) && + sizeof( pPollSet->fd ) == sizeof( fds[ 0 ].fd ) && + sizeof( pPollSet->events ) == sizeof( fds[ 0 ].events ) && + sizeof( pPollSet->revents ) == sizeof( fds[ 0 ].revents ) && + HB_POLLIN == POLLIN && HB_POLLPRI == POLLPRI && + HB_POLLOUT == POLLOUT && HB_POLLERR == POLLERR && + HB_POLLHUP == POLLHUP && HB_POLLNVAL == POLLNVAL; + + HB_MAXUINT timer; + void * pFree = NULL; + int i; + + if( s_fSamePoll ) + pfds = ( struct pollfd * ) pPollSet; + else + { + if( iCount <= ( int ) HB_SIZEOFARRAY( fds ) ) + pfds = fds; + else + pfds = ( struct pollfd * ) ( pFree = hb_xgrab( sizeof( struct pollfd ) * iCount ) ); + + for( i = 0; i < iCount; ++i ) + { + pfds[ i ].fd = pPollSet[ i ].fd; + pfds[ i ].events = ( ( pPollSet[ i ].events & HB_POLLIN ) ? POLLIN : 0 ) | + ( ( pPollSet[ i ].events & HB_POLLPRI ) ? POLLPRI : 0 ) | + ( ( pPollSet[ i ].events & HB_POLLOUT ) ? POLLOUT : 0 ) | + ( ( pPollSet[ i ].events & HB_POLLERR ) ? POLLERR : 0 ) | + ( ( pPollSet[ i ].events & HB_POLLHUP ) ? POLLHUP : 0 ) | + ( ( pPollSet[ i ].events & HB_POLLNVAL ) ? POLLNVAL : 0 ); + pfds[ i ].revents = 0; + } + } + + timer = hb_timerInit( nTimeOut ); + for( ;; ) + { + HB_BOOL fLast = nTimeOut >= 0 && nTimeOut <= 1000; + int tout = fLast ? ( int ) nTimeOut : 1000; + + iResult = poll( pfds, iCount, tout ); + hb_fsSetIOError( iResult >= 0, 0 ); + if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR ) + { + iResult = 0; + fLast = HB_FALSE; + } + if( iResult == 0 && ! fLast && hb_vmRequestQuery() == 0 && + ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) != 0 ) + continue; + + break; + } + + if( ! s_fSamePoll ) + { + for( i = 0; i < iCount; ++i ) + { + pPollSet[ i ].revents = ( ( pfds[ i ].revents & POLLIN ) ? HB_POLLIN : 0 ) | + ( ( pfds[ i ].revents & POLLPRI ) ? HB_POLLPRI : 0 ) | + ( ( pfds[ i ].revents & POLLOUT ) ? HB_POLLOUT : 0 ) | + ( ( pfds[ i ].revents & POLLERR ) ? HB_POLLERR : 0 ) | + ( ( pfds[ i ].revents & POLLHUP ) ? HB_POLLHUP : 0 ) | + ( ( pfds[ i ].revents & POLLNVAL ) ? HB_POLLNVAL : 0 ); + } + } + + if( pFree ) + hb_xfree( pFree ); +} +#elif ! defined( HB_OS_SYMBIAN ) /* ! HB_HAS_POLL */ +{ +# if ! defined( HB_HAS_SELECT_TIMER ) + HB_MAXUINT timer = hb_timerInit( nTimeOut ); +# endif + fd_set rfds, wfds, efds; + int i; + + for( ;; ) + { + struct timeval tv; + int iMaxFD = 0; + HB_BOOL fLast = nTimeOut >= 0 && nTimeOut <= 1000; + + if( fLast ) + { + tv.tv_sec = ( long ) ( nTimeOut / 1000 ); + tv.tv_usec = ( long ) ( nTimeOut % 1000 ) * 1000; + } + else + { + tv.tv_sec = 1; + tv.tv_usec = 0; + } + + FD_ZERO( &rfds ); + FD_ZERO( &wfds ); + FD_ZERO( &efds ); + + for( i = 0; i < iCount; ++i ) + { + PHB_POLLFD pSet = pPollSet + i; + if( pSet->fd >= 0 && + ( pSet->events & ( HB_POLLIN | HB_POLLOUT | HB_POLLPRI ) ) ) + { + if( pSet->events & HB_POLLIN ) + FD_SET( pSet->fd, &rfds ); + if( pSet->events & HB_POLLOUT ) + FD_SET( pSet->fd, &wfds ); + if( pSet->events & HB_POLLPRI ) + FD_SET( pSet->fd, &efds ); + if( pSet->fd > iMaxFD ) + iMaxFD = pSet->fd; + } + } + + iResult = select( iMaxFD + 1, &rfds, &wfds, &efds, &tv ); + hb_fsSetIOError( iResult >= 0, 0 ); + + if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR ) + { + iResult = 0; + fLast = HB_FALSE; +# if defined( HB_HAS_SELECT_TIMER ) + if( nTimeOut > 0 ) + nTimeOut += tv.tv_sec * 1000 + tv.tv_usec / 1000; +# endif + } +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult == 0 && nTimeOut > 0 ) + { + if( ( nTimeOut -= 1000 ) < 0 ) + break; + } + + if( iResult != 0 || fLast || nTimeOut == 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || fLast || ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; +# endif + } + if( iResult > 0 ) + { + iResult = 0; + for( i = 0; i < iCount; ++i ) + { + PHB_POLLFD pSet = pPollSet + i; + pSet->revents = 0; + if( pSet->fd >= 0 ) + { + if( FD_ISSET( pSet->fd, &rfds ) ) + pSet->revents |= HB_POLLIN; + if( FD_ISSET( pSet->fd, &wfds ) ) + pSet->revents |= HB_POLLOUT; + if( FD_ISSET( pSet->fd, &efds ) ) + pSet->revents |= HB_POLLPRI; + if( pSet->revents != 0 ) + ++iResult; + } + } + } +} +#else +{ + int iTODO; /* TODO: for given platform */ + + HB_SYMBOL_UNUSED( pPollSet ); + HB_SYMBOL_UNUSED( iCount ); + HB_SYMBOL_UNUSED( nTimeOut ); + iResult = -1; +} +#endif /* ! HB_HAS_POLL */ + + hb_vmLock(); + + return iResult; +} +#endif /* HB_OS_UNIX */ + HB_FHANDLE hb_fsPOpen( const char * pszFileName, const char * pszMode ) { HB_FHANDLE hFileHandle = FS_ERROR; @@ -1092,7 +1417,7 @@ HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) { - HB_MAXUINT end_timer = nTimeOut > 0 ? hb_dateMilliSeconds() + nTimeOut : 0; + HB_MAXUINT timer = hb_timerInit( nTimeOut ); HB_BOOL fResult = HB_FALSE; DWORD dwAvail; @@ -1112,8 +1437,7 @@ HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, hb_fsSetIOError( fResult, 0 ); } while( fResult && dwAvail == 0 && - ( nTimeOut < 0 || ( end_timer > 0 && - end_timer > hb_dateMilliSeconds() ) ) && + ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) != 0 && hb_vmRequestQuery() == 0 ); if( ! fResult ) @@ -1134,7 +1458,7 @@ HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, # else - HB_MAXUINT end_timer = nTimeOut > 0 ? hb_dateMilliSeconds() + nTimeOut : 0; + HB_MAXUINT timer = hb_timerInit( nTimeOut ); HB_BOOL fResult = HB_FALSE; AVAILDATA avail; @@ -1155,8 +1479,7 @@ HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, ( avail.cbpipe != 0 || ulState == NP_STATE_CONNECTED ); } while( fResult && avail.cbpipe == 0 && - ( nTimeOut < 0 || ( end_timer > 0 && - end_timer > hb_dateMilliSeconds() ) ) && + ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) != 0 && hb_vmRequestQuery() == 0 ); if( ! fResult ) @@ -1166,104 +1489,9 @@ HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, nBufferSize; # endif } -#elif defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN ) +#elif defined( HB_OS_UNIX ) { - int iResult; - -#if defined( HB_HAS_POLL ) - HB_MAXUINT timer = nTimeOut <= 0 ? 0 : hb_dateMilliSeconds(); - struct pollfd fds; - - fds.fd = hPipeHandle; - fds.events = POLLIN; - fds.revents = 0; - - for( ;; ) - { - HB_BOOL fLast = nTimeOut >= 0 && nTimeOut <= 1000; - int tout = fLast ? ( int ) nTimeOut : 1000; - iResult = poll( &fds, 1, tout ); - hb_fsSetIOError( iResult >= 0, 0 ); - if( iResult > 0 && ( fds.revents & POLLIN ) == 0 ) - { - if( ( fds.revents & ( POLLHUP | POLLNVAL | POLLERR ) ) != 0 ) - { - iResult = -1; - break; - } - iResult = 0; - } - else if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR ) - { - iResult = 0; - fLast = HB_FALSE; - } - if( iResult == 0 && ! fLast && hb_vmRequestQuery() == 0 ) - { - if( nTimeOut < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - nTimeOut -= timecurr - timer; - if( nTimeOut > 0 ) - continue; - } - } - } - break; - } -#else /* ! HB_HAS_POLL */ - struct timeval tv; - fd_set rfds; -# if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = nTimeOut <= 0 ? 0 : hb_dateMilliSeconds(); -# else - tv.tv_sec = ( long ) nTimeOut / 1000; - tv.tv_usec = ( long ) ( nTimeOut % 1000 ) * 1000; -# endif - - for( ;; ) - { - if( nTimeOut < 0 ) - { - tv.tv_sec = 1; - tv.tv_usec = 0; - } -# if ! defined( HB_HAS_SELECT_TIMER ) - else - { - tv.tv_sec = ( long ) nTimeOut / 1000; - tv.tv_usec = ( long ) ( nTimeOut % 1000 ) * 1000; - } -# endif - - FD_ZERO( &rfds ); - FD_SET( hPipeHandle, &rfds ); - iResult = select( hPipeHandle + 1, &rfds, NULL, NULL, &tv ); - hb_fsSetIOError( iResult >= 0, 0 ); - if( nTimeOut < 0 && iResult == 0 && hb_vmRequestQuery() == 0 ) - continue; - if( iResult != -1 || nTimeOut == 0 || - hb_fsOsError() != ( HB_ERRCODE ) EINTR || - hb_vmRequestQuery() != 0 ) - break; -# if ! defined( HB_HAS_SELECT_TIMER ) - else if( nTimeOut > 0 ) - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - if( ( nTimeOut -= timecurr - timer ) <= 0 ) - break; - timer = timecurr; - } - } -# endif - } -#endif /* ! HB_HAS_POLL */ + int iResult = hb_fsCanRead( hPipeHandle, nTimeOut ); if( iResult > 0 ) nToRead = nBufferSize; @@ -1321,7 +1549,7 @@ HB_SIZE hb_fsPipeWrite( HB_FHANDLE hPipeHandle, const void * buffer, HB_SIZE nSi if( GetNamedPipeHandleState( hPipe, &dwMode, NULL, NULL, NULL, NULL, 0 ) ) { - HB_MAXUINT end_timer = nTimeOut > 0 ? hb_dateMilliSeconds() + nTimeOut : 0; + HB_MAXUINT timer = hb_timerInit( nTimeOut ); HB_BOOL fResult = HB_FALSE; if( ( dwMode & PIPE_NOWAIT ) == 0 ) @@ -1352,8 +1580,7 @@ HB_SIZE hb_fsPipeWrite( HB_FHANDLE hPipeHandle, const void * buffer, HB_SIZE nSi hb_fsSetIOError( fResult, 0 ); } while( fResult && nWritten < nSize && - ( nTimeOut < 0 || ( end_timer > 0 && - end_timer > hb_dateMilliSeconds() ) ) && + ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) != 0 && hb_vmRequestQuery() == 0 ); if( ( dwMode & PIPE_NOWAIT ) == 0 ) @@ -1380,7 +1607,7 @@ HB_SIZE hb_fsPipeWrite( HB_FHANDLE hPipeHandle, const void * buffer, HB_SIZE nSi ret = DosQueryNPHState( ( HPIPE ) hPipeHandle, &state ); if( ret == NO_ERROR ) { - HB_MAXUINT end_timer = nTimeOut > 0 ? hb_dateMilliSeconds() + nTimeOut : 0; + HB_MAXUINT timer = hb_timerInit( nTimeOut ); HB_BOOL fResult = HB_FALSE; if( ( state & NP_NOWAIT ) == 0 ) @@ -1401,8 +1628,7 @@ HB_SIZE hb_fsPipeWrite( HB_FHANDLE hPipeHandle, const void * buffer, HB_SIZE nSi nWritten = fResult ? ( HB_SIZE ) cbActual : ( HB_SIZE ) FS_ERROR; } while( fResult && nWritten == 0 && - ( nTimeOut < 0 || ( end_timer > 0 && - end_timer > hb_dateMilliSeconds() ) ) && + ( nTimeOut = hb_timerTest( nTimeOut, &timer ) ) != 0 && hb_vmRequestQuery() == 0 ); if( ( state & NP_NOWAIT ) == 0 ) @@ -1415,105 +1641,9 @@ HB_SIZE hb_fsPipeWrite( HB_FHANDLE hPipeHandle, const void * buffer, HB_SIZE nSi } # endif } -#elif defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN ) +#elif defined( HB_OS_UNIX ) { - int iResult; - -#if defined( HB_HAS_POLL ) - HB_MAXUINT timer = nTimeOut <= 0 ? 0 : hb_dateMilliSeconds(); - struct pollfd fds; - - fds.fd = hPipeHandle; - fds.events = POLLOUT; - fds.revents = 0; - - for( ;; ) - { - HB_BOOL fLast = nTimeOut >= 0 && nTimeOut <= 1000; - int tout = fLast ? ( int ) nTimeOut : 1000; - - iResult = poll( &fds, 1, tout ); - hb_fsSetIOError( iResult >= 0, 0 ); - if( iResult > 0 && ( fds.revents & POLLOUT ) == 0 ) - { - if( ( fds.revents & ( POLLHUP | POLLNVAL | POLLERR ) ) != 0 ) - { - iResult = -1; - break; - } - iResult = 0; - } - else if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR ) - { - iResult = 0; - fLast = HB_FALSE; - } - if( iResult == 0 && ! fLast && hb_vmRequestQuery() == 0 ) - { - if( nTimeOut < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - nTimeOut -= timecurr - timer; - if( nTimeOut > 0 ) - continue; - } - } - } - break; - } -#else /* ! HB_HAS_POLL */ - struct timeval tv; - fd_set wfds; -# if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = nTimeOut <= 0 ? 0 : hb_dateMilliSeconds(); -# else - tv.tv_sec = ( long ) nTimeOut / 1000; - tv.tv_usec = ( long ) ( nTimeOut % 1000 ) * 1000; -# endif - - for( ;; ) - { - if( nTimeOut < 0 ) - { - tv.tv_sec = 1; - tv.tv_usec = 0; - } -# if ! defined( HB_HAS_SELECT_TIMER ) - else - { - tv.tv_sec = ( long ) nTimeOut / 1000; - tv.tv_usec = ( long ) ( nTimeOut % 1000 ) * 1000; - } -# endif - - FD_ZERO( &wfds ); - FD_SET( hPipeHandle, &wfds ); - iResult = select( hPipeHandle + 1, NULL, &wfds, NULL, &tv ); - hb_fsSetIOError( iResult >= 0, 0 ); - if( nTimeOut < 0 && iResult == 0 && hb_vmRequestQuery() == 0 ) - continue; - if( iResult != -1 || nTimeOut == 0 || - hb_fsOsError() != ( HB_ERRCODE ) EINTR || - hb_vmRequestQuery() != 0 ) - break; -# if ! defined( HB_HAS_SELECT_TIMER ) - else if( nTimeOut > 0 ) - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - if( ( nTimeOut -= timecurr - timer ) <= 0 ) - break; - timer = timecurr; - } - } -# endif - } -#endif /* ! HB_HAS_POLL */ + int iResult = hb_fsCanWrite( hPipeHandle, nTimeOut ); if( iResult > 0 ) { diff --git a/src/rtl/gtcrs/gtcrs.c b/src/rtl/gtcrs/gtcrs.c index fe782cbd85..bac71ec632 100644 --- a/src/rtl/gtcrs/gtcrs.c +++ b/src/rtl/gtcrs/gtcrs.c @@ -72,6 +72,7 @@ typedef struct int fd; int mode; int status; + int index; void * data; int ( * eventFunc )( int, int, void * ); } evtFD; @@ -147,6 +148,7 @@ typedef struct InOutBase int stdin_ptr_r; int stdin_inbuf; + PHB_POLLFD pPollSet; evtFD ** event_fds; int efds_size; int efds_no; @@ -406,13 +408,12 @@ static int add_efds( InOutBase * ioBase, int fd, int mode, { if( ioBase->efds_size <= ioBase->efds_no ) { - if( ioBase->event_fds == NULL ) - ioBase->event_fds = ( evtFD ** ) - hb_xgrab( ( ioBase->efds_size += 10 ) * sizeof( evtFD * ) ); - else - ioBase->event_fds = ( evtFD ** ) + ioBase->event_fds = ( evtFD ** ) hb_xrealloc( ioBase->event_fds, ( ioBase->efds_size += 10 ) * sizeof( evtFD * ) ); + ioBase->pPollSet = ( PHB_POLLFD ) + hb_xrealloc( ioBase->pPollSet, + ioBase->efds_size * sizeof( HB_POLLFD ) ); } pefd = ( evtFD * ) hb_xgrab( sizeof( evtFD ) ); @@ -454,8 +455,10 @@ static void del_all_efds( InOutBase * ioBase ) hb_xfree( ioBase->event_fds[ i ] ); hb_xfree( ioBase->event_fds ); + hb_xfree( ioBase->pPollSet ); ioBase->event_fds = NULL; + ioBase->pPollSet = NULL; ioBase->efds_no = ioBase->efds_size = 0; } } @@ -683,13 +686,7 @@ static void flush_gpmevt( mouseEvent * mEvt ) { if( gpm_fd >= 0 ) { - struct timeval tv = { 0, 0 }; - fd_set rfds; - - FD_ZERO( &rfds ); - FD_SET( gpm_fd, &rfds ); - - while( select( gpm_fd + 1, &rfds, NULL, NULL, &tv ) > 0 ) + while( hb_fsCanRead( gpm_fd, 0 ) > 0 ) set_gpmevt( gpm_fd, O_RDONLY, ( void * ) mEvt ); while( getMouseKey( mEvt ) ) ; @@ -802,58 +799,51 @@ static int read_bufch( InOutBase * ioBase, int fd ) return n; } -static int get_inch( InOutBase * ioBase, int milisec ) +static int get_inch( InOutBase * ioBase, HB_MAXINT timeout ) { - int nRet = 0, npfd = -1, nchk = ioBase->efds_no, lRead = 0; + int nRet = 0, nNext = 0, npfd = -1, nchk = ioBase->efds_no, lRead = 0; int mode, i, n, counter; - struct timeval tv, * ptv; evtFD * pefd = NULL; - fd_set rfds, wfds; + HB_MAXUINT timer; - if( milisec == 0 ) - ptv = NULL; - else - { - if( milisec < 0 ) - milisec = 0; - tv.tv_sec = ( milisec / 1000 ); - tv.tv_usec = ( milisec % 1000 ) * 1000; - ptv = &tv; - } + timer = hb_timerInit( timeout ); - while( nRet == 0 && lRead == 0 ) + do { - n = -1; - FD_ZERO( &rfds ); - FD_ZERO( &wfds ); - for( i = 0; i < ioBase->efds_no; i++ ) + for( i = n = 0; i < ioBase->efds_no; i++ ) { if( ioBase->event_fds[ i ]->status == EVTFDSTAT_RUN ) { - if( ioBase->event_fds[ i ]->mode == O_RDWR - || ioBase->event_fds[ i ]->mode == O_RDONLY ) - { - FD_SET( ioBase->event_fds[ i ]->fd, &rfds ); - if( n < ioBase->event_fds[ i ]->fd ) - n = ioBase->event_fds[ i ]->fd; - } - if( ioBase->event_fds[ i ]->mode == O_RDWR - || ioBase->event_fds[ i ]->mode == O_WRONLY ) - { - FD_SET( ioBase->event_fds[ i ]->fd, &wfds ); - if( n < ioBase->event_fds[ i ]->fd ) - n = ioBase->event_fds[ i ]->fd; - } + ioBase->pPollSet[ n ].fd = ioBase->event_fds[ i ]->fd; + ioBase->pPollSet[ n ].events = 0; + ioBase->pPollSet[ n ].revents = 0; + if( ioBase->event_fds[ i ]->mode == O_RDWR || + ioBase->event_fds[ i ]->mode == O_RDONLY ) + ioBase->pPollSet[ n ].events |= HB_POLLIN; + if( ioBase->event_fds[ i ]->mode == O_RDWR || + ioBase->event_fds[ i ]->mode == O_WRONLY ) + ioBase->pPollSet[ n ].events |= HB_POLLOUT; + ioBase->event_fds[ i ]->index = n++; + } + else + { + ioBase->event_fds[ i ]->index = -1; + if( ioBase->event_fds[ i ]->status == EVTFDSTAT_STOP && + ioBase->event_fds[ i ]->eventFunc == NULL ) + nNext = HB_INKEY_NEW_EVENT( HB_K_TERMINATE ); } } counter = ioBase->key_counter; - if( select( n + 1, &rfds, &wfds, NULL, ptv ) > 0 ) + if( hb_fsPoll( ioBase->pPollSet, n, timeout ) > 0 ) { for( i = 0; i < ioBase->efds_no; i++ ) { - n = ( FD_ISSET( ioBase->event_fds[ i ]->fd, &rfds ) ? 1 : 0 ) | - ( FD_ISSET( ioBase->event_fds[ i ]->fd, &wfds ) ? 2 : 0 ); + n = ioBase->event_fds[ i ]->index; + if( n < 0 ) + continue; + n = ioBase->pPollSet[ n ].revents; + n = ( ( n & HB_POLLIN ) ? 1 : 0 ) | ( ( n & HB_POLLOUT ) ? 2 : 0 ); if( n != 0 ) { if( ioBase->event_fds[ i ]->eventFunc == NULL ) @@ -861,7 +851,10 @@ static int get_inch( InOutBase * ioBase, int milisec ) lRead = 1; n = read_bufch( ioBase, ioBase->event_fds[ i ]->fd ); if( n == 0 ) + { ioBase->event_fds[ i ]->status = EVTFDSTAT_STOP; + nRet = HB_INKEY_NEW_EVENT( HB_K_CLOSE ); + } } else if( nRet == 0 && counter == ioBase->key_counter ) { @@ -902,6 +895,8 @@ static int get_inch( InOutBase * ioBase, int milisec ) else lRead = 1; } + while( nRet == 0 && lRead == 0 && + ( timeout = hb_timerTest( timeout, &timer ) ) != 0 ); for( i = n = nchk; i < ioBase->efds_no; i++ ) { @@ -920,7 +915,7 @@ static int get_inch( InOutBase * ioBase, int milisec ) ioBase->event_fds[ n++ ] = pefd; ioBase->efds_no = n; - return nRet; + return nRet == 0 ? nNext : nRet; } static int test_bufch( InOutBase * ioBase, int n, int delay ) @@ -2290,7 +2285,7 @@ int HB_GT_FUNC( gt_CloseTerm( int iHandle ) ) int HB_GT_FUNC( gt_WaitKey( double dTimeOut ) ) { - return wait_key( s_ioBase, ( int ) ( dTimeOut * 1000.0 ) ); + return wait_key( s_ioBase, ( int ) ( dTimeOut >= 0 ? dTimeOut * 1000.0 : -1 ) ); } int HB_GT_FUNC( gt_AddKeyMap( int iKey, char * szSequence ) ) @@ -2679,7 +2674,7 @@ static int hb_gt_crs_ReadKey( PHB_GT pGT, int iEventMask ) HB_SYMBOL_UNUSED( iEventMask ); - iKey = wait_key( s_ioBase, -1 ); + iKey = wait_key( s_ioBase, 0 ); if( iKey == K_RESIZE ) { diff --git a/src/rtl/gtcrs/gtcrs.h b/src/rtl/gtcrs/gtcrs.h index 11b9f8ef2d..5568e36bac 100644 --- a/src/rtl/gtcrs/gtcrs.h +++ b/src/rtl/gtcrs/gtcrs.h @@ -54,6 +54,8 @@ #include "hbinit.h" #include "hbapiitm.h" #include "hbapierr.h" +#include "hbapifs.h" +#include "hbdate.h" #include "hbapicdp.h" diff --git a/src/rtl/gtpca/gtpca.c b/src/rtl/gtpca/gtpca.c index 1756625f1c..32267be1d5 100644 --- a/src/rtl/gtpca/gtpca.c +++ b/src/rtl/gtpca/gtpca.c @@ -235,7 +235,8 @@ static void hb_gt_pca_AnsiGetCurPos( int * iRow, int * iCol ) { char rdbuf[ 64 ]; int i, j, n, d, y, x; - HB_MAXUINT end_timer, time; + HB_MAXINT timeout; + HB_MAXUINT timer; hb_gt_pca_termOut( "\x1B[6n", 4 ); hb_gt_pca_termFlush(); @@ -243,7 +244,8 @@ static void hb_gt_pca_AnsiGetCurPos( int * iRow, int * iCol ) n = j = x = y = 0; /* wait up to 2 seconds for answer */ - end_timer = hb_dateMilliSeconds() + 2000; + timeout = 2000; + timer = hb_timerInit( timeout ); for( ;; ) { /* loking for cursor position in "\033[%d;%dR" */ @@ -279,23 +281,13 @@ static void hb_gt_pca_AnsiGetCurPos( int * iRow, int * iCol ) } if( n == ( int ) sizeof( rdbuf ) ) break; - time = hb_dateMilliSeconds(); - if( time > end_timer ) + + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) break; else { #if defined( HB_HAS_TERMIOS ) - struct timeval tv; - fd_set rdfds; - int iMilliSec; - - FD_ZERO( &rdfds ); - FD_SET( s_hFilenoStdin, &rdfds ); - iMilliSec = ( int ) ( end_timer - time ); - tv.tv_sec = iMilliSec / 1000; - tv.tv_usec = ( iMilliSec % 1000 ) * 1000; - - if( select( s_hFilenoStdin + 1, &rdfds, NULL, NULL, &tv ) <= 0 ) + if( hb_fsCanRead( s_hFilenoStdin, timeout ) <= 0 ) break; i = read( s_hFilenoStdin, rdbuf + n, sizeof( rdbuf ) - n ); #else @@ -612,19 +604,11 @@ static int hb_gt_pca_ReadKey( PHB_GT pGT, int iEventMask ) ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); #elif defined( HB_HAS_TERMIOS ) + if( hb_fsCanRead( s_hFilenoStdin, 0 ) > 0 ) { - struct timeval tv; - fd_set rfds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO( &rfds ); - FD_SET( s_hFilenoStdin, &rfds ); - if( select( s_hFilenoStdin + 1, &rfds, NULL, NULL, &tv ) > 0 ) - { - HB_BYTE bChar; - if( hb_fsRead( s_hFilenoStdin, &bChar, 1 ) == 1 ) - ch = bChar; - } + HB_BYTE bChar; + if( hb_fsRead( s_hFilenoStdin, &bChar, 1 ) == 1 ) + ch = bChar; } #elif defined( _MSC_VER ) && ! defined( HB_OS_WIN_CE ) if( s_bStdinConsole ) diff --git a/src/rtl/gtsln/gtsln.c b/src/rtl/gtsln/gtsln.c index 5fd1c5399b..a3a0bd0466 100644 --- a/src/rtl/gtsln/gtsln.c +++ b/src/rtl/gtsln/gtsln.c @@ -486,11 +486,13 @@ static int hb_sln_isUTF8( int iStdOut, int iStdIn ) { char rdbuf[ 64 ]; int i, j, n, d, y, x; - HB_MAXUINT end_timer, cur_time; + HB_MAXINT timeout; + HB_MAXUINT timer; n = j = x = y = 0; /* wait up to 2 seconds for answer */ - end_timer = hb_dateMilliSeconds() + 2000; + timeout = 2000; + timer = hb_timerInit( timeout ); for( ;; ) { /* loking for cursor position in "\033[%d;%dR" */ @@ -525,22 +527,12 @@ static int hb_sln_isUTF8( int iStdOut, int iStdIn ) } if( n == sizeof( rdbuf ) ) break; - cur_time = hb_dateMilliSeconds(); - if( cur_time > end_timer ) + + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) break; else { - struct timeval tv; - fd_set rdfds; - int iMilliSec; - - FD_ZERO( &rdfds ); - FD_SET( iStdIn, &rdfds ); - iMilliSec = ( int ) ( end_timer - cur_time ); - tv.tv_sec = iMilliSec / 1000; - tv.tv_usec = ( iMilliSec % 1000 ) * 1000; - - if( select( iStdIn + 1, &rdfds, NULL, NULL, &tv ) <= 0 ) + if( hb_fsCanRead( iStdIn, timeout ) <= 0 ) break; i = read( iStdIn, rdbuf + n, sizeof( rdbuf ) - n ); if( i <= 0 ) diff --git a/src/rtl/gtsln/mousesln.c b/src/rtl/gtsln/mousesln.c index 0ac383054b..2cedc681bc 100644 --- a/src/rtl/gtsln/mousesln.c +++ b/src/rtl/gtsln/mousesln.c @@ -78,15 +78,8 @@ static HB_BOOL GetGpmEvent( Gpm_Event * Evt ) { if( s_bMousePresent && gpm_fd >= 0 ) { - struct timeval tv = { 0, 0 }; - fd_set ReadFD; - - FD_ZERO( &ReadFD ); - FD_SET( gpm_fd, &ReadFD ); - - if( select( gpm_fd + 1, &ReadFD, NULL, NULL, &tv ) > 0 ) - if( FD_ISSET( gpm_fd, &ReadFD ) ) - return Gpm_GetEvent( Evt ) > 0; + if( hb_fsCanRead( gpm_fd, 0 ) > 0 ) + return Gpm_GetEvent( Evt ) > 0; } return HB_FALSE; diff --git a/src/rtl/gtstd/gtstd.c b/src/rtl/gtstd/gtstd.c index 8c1c90595e..b61ac5d6d8 100644 --- a/src/rtl/gtstd/gtstd.c +++ b/src/rtl/gtstd/gtstd.c @@ -330,19 +330,11 @@ static int hb_gt_std_ReadKey( PHB_GT pGT, int iEventMask ) pGTSTD = HB_GTSTD_GET( pGT ); #if defined( HB_HAS_TERMIOS ) + if( hb_fsCanRead( pGTSTD->hStdin, 0 ) > 0 ) { - struct timeval tv; - fd_set rfds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO( &rfds ); - FD_SET( pGTSTD->hStdin, &rfds ); - if( select( pGTSTD->hStdin + 1, &rfds, NULL, NULL, &tv ) > 0 ) - { - HB_BYTE bChar; - if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) - ch = bChar; - } + HB_BYTE bChar; + if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) + ch = bChar; } #elif defined( _MSC_VER ) && ! defined( HB_OS_WIN_CE ) if( pGTSTD->fStdinConsole ) diff --git a/src/rtl/gttrm/gttrm.c b/src/rtl/gttrm/gttrm.c index 6ecc09724c..f24493f4fa 100644 --- a/src/rtl/gttrm/gttrm.c +++ b/src/rtl/gttrm/gttrm.c @@ -245,6 +245,7 @@ typedef struct int fd; int mode; int status; + int index; void * cargo; int ( * eventFunc )( int, int, void * ); } evtFD; @@ -371,6 +372,7 @@ typedef struct _HB_GTTRM int stdin_ptr_r; int stdin_inbuf; + PHB_POLLFD pPollSet; evtFD ** event_fds; int efds_size; int efds_no; @@ -667,13 +669,12 @@ static int add_efds( PHB_GTTRM pTerm, int fd, int mode, { if( pTerm->efds_size <= pTerm->efds_no ) { - if( pTerm->event_fds == NULL ) - pTerm->event_fds = ( evtFD ** ) - hb_xgrab( ( pTerm->efds_size += 10 ) * sizeof( evtFD * ) ); - else - pTerm->event_fds = ( evtFD ** ) + pTerm->event_fds = ( evtFD ** ) hb_xrealloc( pTerm->event_fds, ( pTerm->efds_size += 10 ) * sizeof( evtFD * ) ); + pTerm->pPollSet = ( PHB_POLLFD ) + hb_xrealloc( pTerm->pPollSet, + pTerm->efds_size * sizeof( HB_POLLFD ) ); } pefd = ( evtFD * ) hb_xgrab( sizeof( evtFD ) ); @@ -682,7 +683,7 @@ static int add_efds( PHB_GTTRM pTerm, int fd, int mode, pefd->cargo = cargo; pefd->eventFunc = eventFunc; pefd->status = EVTFDSTAT_RUN; - pTerm->event_fds[pTerm->efds_no++] = pefd; + pTerm->event_fds[ pTerm->efds_no++ ] = pefd; } return fd; @@ -717,8 +718,10 @@ static void del_all_efds( PHB_GTTRM pTerm ) hb_xfree( pTerm->event_fds[ i ] ); hb_xfree( pTerm->event_fds ); + hb_xfree( pTerm->pPollSet ); pTerm->event_fds = NULL; + pTerm->pPollSet = NULL; pTerm->efds_no = pTerm->efds_size = 0; } } @@ -964,13 +967,7 @@ static void flush_gpmevt( PHB_GTTRM pTerm ) { if( gpm_fd >= 0 ) { - struct timeval tv = { 0, 0 }; - fd_set rfds; - - FD_ZERO( &rfds ); - FD_SET( gpm_fd, &rfds ); - - while( select( gpm_fd + 1, &rfds, NULL, NULL, &tv ) > 0 ) + while( hb_fsCanRead( gpm_fd, 0 ) > 0 ) set_gpmevt( gpm_fd, O_RDONLY, ( void * ) pTerm ); while( getMouseKey( &pTerm->mLastEvt ) ) ; @@ -1082,61 +1079,51 @@ static int read_bufch( PHB_GTTRM pTerm, int fd ) return n; } -static int get_inch( PHB_GTTRM pTerm, int milisec ) +static int get_inch( PHB_GTTRM pTerm, HB_MAXINT timeout ) { int nRet = 0, nNext = 0, npfd = -1, nchk = pTerm->efds_no, lRead = 0; int mode, i, n, counter; - struct timeval tv, * ptv; evtFD * pefd = NULL; - fd_set rfds, wfds; + HB_MAXUINT timer; - if( milisec == 0 ) - ptv = NULL; - else - { - if( milisec < 0 ) - milisec = 0; - tv.tv_sec = ( milisec / 1000 ); - tv.tv_usec = ( milisec % 1000 ) * 1000; - ptv = &tv; - } + timer = hb_timerInit( timeout ); - while( nRet == 0 && lRead == 0 ) + do { - n = -1; - FD_ZERO( &rfds ); - FD_ZERO( &wfds ); - for( i = 0; i < pTerm->efds_no; i++ ) + for( i = n = 0; i < pTerm->efds_no; i++ ) { if( pTerm->event_fds[ i ]->status == EVTFDSTAT_RUN ) { + pTerm->pPollSet[ n ].fd = pTerm->event_fds[ i ]->fd; + pTerm->pPollSet[ n ].events = 0; + pTerm->pPollSet[ n ].revents = 0; if( pTerm->event_fds[ i ]->mode == O_RDWR || pTerm->event_fds[ i ]->mode == O_RDONLY ) - { - FD_SET( pTerm->event_fds[ i ]->fd, &rfds ); - if( n < pTerm->event_fds[ i ]->fd ) - n = pTerm->event_fds[ i ]->fd; - } + pTerm->pPollSet[ n ].events |= HB_POLLIN; if( pTerm->event_fds[ i ]->mode == O_RDWR || pTerm->event_fds[ i ]->mode == O_WRONLY ) - { - FD_SET( pTerm->event_fds[ i ]->fd, &wfds ); - if( n < pTerm->event_fds[ i ]->fd ) - n = pTerm->event_fds[ i ]->fd; - } + pTerm->pPollSet[ n ].events |= HB_POLLOUT; + pTerm->event_fds[ i ]->index = n++; + } + else + { + pTerm->event_fds[ i ]->index = -1; + if( pTerm->event_fds[ i ]->status == EVTFDSTAT_STOP && + pTerm->event_fds[ i ]->eventFunc == NULL ) + nNext = HB_INKEY_NEW_EVENT( HB_K_TERMINATE ); } - else if( pTerm->event_fds[ i ]->status == EVTFDSTAT_STOP && - pTerm->event_fds[ i ]->eventFunc == NULL ) - nNext = HB_INKEY_NEW_EVENT( HB_K_TERMINATE ); } counter = pTerm->key_counter; - if( select( n + 1, &rfds, &wfds, NULL, ptv ) > 0 ) + if( hb_fsPoll( pTerm->pPollSet, n, timeout ) > 0 ) { for( i = 0; i < pTerm->efds_no; i++ ) { - n = ( FD_ISSET( pTerm->event_fds[ i ]->fd, &rfds ) ? 1 : 0 ) | - ( FD_ISSET( pTerm->event_fds[ i ]->fd, &wfds ) ? 2 : 0 ); + n = pTerm->event_fds[ i ]->index; + if( n < 0 ) + continue; + n = pTerm->pPollSet[ n ].revents; + n = ( ( n & HB_POLLIN ) ? 1 : 0 ) | ( ( n & HB_POLLOUT ) ? 2 : 0 ); if( n != 0 ) { if( pTerm->event_fds[ i ]->eventFunc == NULL ) @@ -1188,6 +1175,8 @@ static int get_inch( PHB_GTTRM pTerm, int milisec ) else lRead = 1; } + while( nRet == 0 && lRead == 0 && + ( timeout = hb_timerTest( timeout, &timer ) ) != 0 ); for( i = n = nchk; i < pTerm->efds_no; i++ ) { @@ -1979,7 +1968,8 @@ static HB_BOOL hb_gt_trm_AnsiGetCursorPos( PHB_GTTRM pTerm, int * iRow, int * iC { char rdbuf[ 64 ]; int i, j, n, d, y, x; - HB_MAXUINT end_timer, cur_time; + HB_MAXINT timeout; + HB_MAXUINT timer; hb_gt_trm_termOut( pTerm, "\x1B[6n", 4 ); if( szPost ) @@ -1990,7 +1980,8 @@ static HB_BOOL hb_gt_trm_AnsiGetCursorPos( PHB_GTTRM pTerm, int * iRow, int * iC pTerm->fPosAnswer = HB_FALSE; /* wait up to 2 seconds for answer */ - end_timer = hb_dateMilliSeconds() + 2000; + timeout = 2000; + timer = hb_timerInit( timeout ); for( ;; ) { /* loking for cursor position in "\033[%d;%dR" */ @@ -2038,23 +2029,13 @@ static HB_BOOL hb_gt_trm_AnsiGetCursorPos( PHB_GTTRM pTerm, int * iRow, int * iC } if( n == sizeof( rdbuf ) ) break; - cur_time = hb_dateMilliSeconds(); - if( cur_time > end_timer ) + + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) break; else { #if defined( HB_OS_UNIX ) || defined( __DJGPP__ ) - struct timeval tv; - fd_set rdfds; - int iMilliSec; - - FD_ZERO( &rdfds ); - FD_SET( pTerm->hFilenoStdin, &rdfds ); - iMilliSec = ( int ) ( end_timer - cur_time ); - tv.tv_sec = iMilliSec / 1000; - tv.tv_usec = ( iMilliSec % 1000 ) * 1000; - - if( select( pTerm->hFilenoStdin + 1, &rdfds, NULL, NULL, &tv ) <= 0 ) + if( hb_fsCanRead( pTerm->hFilenoStdin, timeout ) <= 0 ) break; i = read( pTerm->hFilenoStdin, rdbuf + n, sizeof( rdbuf ) - n ); #else @@ -3579,7 +3560,7 @@ static int hb_gt_trm_ReadKey( PHB_GT pGT, int iEventMask ) HB_SYMBOL_UNUSED( iEventMask ); - iKey = wait_key( HB_GTTRM_GET( pGT ), -1 ); + iKey = wait_key( HB_GTTRM_GET( pGT ), 0 ); if( iKey == K_RESIZE ) { diff --git a/src/rtl/gtwin/gtwin.c b/src/rtl/gtwin/gtwin.c index 910828278a..351975e640 100644 --- a/src/rtl/gtwin/gtwin.c +++ b/src/rtl/gtwin/gtwin.c @@ -668,11 +668,13 @@ static HWND hb_getConsoleWindowHandle( void ) if( SetConsoleTitle( tmpTitle ) ) { - HB_MAXUINT nTimeOut = hb_dateMilliSeconds() + 200; + HB_MAXINT timeout = 200; + HB_MAXUINT timer = hb_timerInit( timeout ); + /* repeat in a loop to be sure title is changed */ do hWnd = FindWindow( NULL, tmpTitle ); - while( hWnd == NULL && hb_dateMilliSeconds() < nTimeOut ); + while( hWnd == NULL && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 ); SetConsoleTitle( oldTitle ); } } diff --git a/src/rtl/gtxwc/gtxwc.c b/src/rtl/gtxwc/gtxwc.c index 422c0c51ce..aac78f96de 100644 --- a/src/rtl/gtxwc/gtxwc.c +++ b/src/rtl/gtxwc/gtxwc.c @@ -4478,18 +4478,8 @@ static void hb_gt_xwc_RequestSelection( PXWND_DEF wnd ) if( ! wnd->ClipboardRcvd && wnd->ClipboardRequest == aRequest ) { HB_ULONG ulTime = hb_gt_xwc_CurrentTime() - ulCurrentTime; - struct timeval timeout; - fd_set readfds; - if( ulTime > 3000 ) - break; - ulTime = 3000 - ulTime; - timeout.tv_sec = ulTime / 1000; - timeout.tv_usec = ( ulTime % 1000 ) / 1000; - - FD_ZERO( &readfds ); - FD_SET( iConnFD, &readfds ); - if( select( iConnFD + 1, &readfds, NULL, NULL, &timeout ) <= 0 ) + if( ulTime > 3000 || hb_fsCanRead( iConnFD, 3000 - ulTime ) <= 0 ) break; } } @@ -5008,8 +4998,9 @@ static HB_BOOL hb_gt_xwc_SetMode( PHB_GT pGT, int iRow, int iCol ) } else { - HB_MAXUINT nTimeOut = hb_dateMilliSeconds() + 1000; HB_BOOL fResizable = wnd->fResizable; + HB_MAXINT timeout; + HB_MAXUINT timer; #ifdef XWC_DEBUG printf( "SetMode(%d,%d) begin\n", iRow, iCol ); fflush( stdout ); @@ -5024,12 +5015,15 @@ static HB_BOOL hb_gt_xwc_SetMode( PHB_GT pGT, int iRow, int iCol ) hb_gt_xwc_ResizeRequest( wnd, iCol, iRow ); HB_XWC_XLIB_UNLOCK( wnd->dpy ); + timeout = 1000; + timer = hb_timerInit( timeout ); + do { hb_gt_xwc_RealRefresh( wnd, HB_TRUE ); if( iCol == wnd->cols && iRow == wnd->rows ) fResult = HB_TRUE; - else if( hb_dateMilliSeconds() > nTimeOut ) + else if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) break; else hb_releaseCPU(); diff --git a/src/rtl/hbcom.c b/src/rtl/hbcom.c index 6bcc3918d2..5cd8b33645 100644 --- a/src/rtl/hbcom.c +++ b/src/rtl/hbcom.c @@ -483,9 +483,9 @@ int hb_comLastNum( void ) #if defined( HB_HAS_TERMIOS ) -#define HB_COM_IS_EINTR() ( errno == EINTR ) -#define HB_COM_IS_EBADF() ( errno == EBADF ) -#define HB_COM_GETERROR() ( errno ) +#define HB_COM_IS_EINTR( pCom ) ( ( pCom )->oserr == EINTR ) +#define HB_COM_IS_EBADF( pCom ) ( ( pCom )->oserr == EBADF ) +#define HB_COM_GETERROR() ( errno ) #if defined( HB_OS_LINUX ) # define HB_HAS_SELECT_TIMER @@ -539,14 +539,14 @@ static int hb_comCanRead( PHB_COM pCom, HB_MAXINT timeout ) int iResult; #if defined( HB_HAS_POLL ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerInit( timeout ); struct pollfd fds; fds.fd = pCom->fd; fds.events = POLLIN; fds.revents = 0; - for( ;; ) + do { int tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout; iResult = poll( &fds, 1, tout ); @@ -563,34 +563,16 @@ static int hb_comCanRead( PHB_COM pCom, HB_MAXINT timeout ) } iResult = 0; } - if( ( ( iResult == 0 && ( timeout < 0 || timeout > 1000 ) ) || - ( iResult == -1 && timeout != 0 && HB_COM_IS_EINTR() ) ) && - hb_vmRequestQuery() == 0 ) - { - if( timeout < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - continue; - } - } - } - } - break; + else if( iResult == -1 && HB_COM_IS_EINTR( pCom ) ) + iResult = 0; } + while( iResult == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); #else /* ! HB_HAS_POLL */ struct timeval tv; fd_set rfds; - # if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerInit( timeout ); # else tv.tv_sec = ( long ) ( timeout / 1000 ); tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; @@ -598,9 +580,6 @@ static int hb_comCanRead( PHB_COM pCom, HB_MAXINT timeout ) for( ;; ) { - FD_ZERO( &rfds ); - FD_SET( pCom->fd, &rfds ); - if( timeout < 0 ) { tv.tv_sec = 1; @@ -614,26 +593,21 @@ static int hb_comCanRead( PHB_COM pCom, HB_MAXINT timeout ) } # endif + FD_ZERO( &rfds ); + FD_SET( pCom->fd, &rfds ); iResult = select( ( int ) ( pCom->fd + 1 ), &rfds, NULL, NULL, &tv ); + hb_comSetOsError( pCom, iResult == -1 ); if( iResult > 0 && ! FD_ISSET( pCom->fd, &rfds ) ) iResult = 0; - hb_comSetOsError( pCom, iResult == -1 ); - if( iResult == 0 && timeout < 0 && hb_vmRequestQuery() == 0 ) - continue; - if( iResult != -1 || timeout == 0 || ! HB_COM_IS_EINTR() || + else if( iResult == -1 && HB_COM_IS_EINTR( pCom ) ) + iResult = 0; +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult != 0 || timeout >= 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || hb_vmRequestQuery() != 0 ) break; -# if ! defined( HB_HAS_SELECT_TIMER ) - else if( timeout > 0 ) - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - if( ( timeout -= timecurr - timer ) <= 0 ) - break; - timer = timecurr; - } - } # endif } #endif /* ! HB_HAS_POLL */ @@ -646,14 +620,14 @@ static int hb_comCanWrite( PHB_COM pCom, HB_MAXINT timeout ) int iResult; #if defined( HB_HAS_POLL ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerInit( timeout ); struct pollfd fds; fds.fd = pCom->fd; fds.events = POLLOUT; fds.revents = 0; - for( ;; ) + do { int tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout; iResult = poll( &fds, 1, tout ); @@ -670,34 +644,16 @@ static int hb_comCanWrite( PHB_COM pCom, HB_MAXINT timeout ) } iResult = 0; } - if( ( ( iResult == 0 && ( timeout < 0 || timeout > 1000 ) ) || - ( iResult == -1 && timeout != 0 && HB_COM_IS_EINTR() ) ) && - hb_vmRequestQuery() == 0 ) - { - if( timeout < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - continue; - } - } - } - } - break; + else if( iResult == -1 && HB_COM_IS_EINTR( pCom ) ) + iResult = 0; } + while( iResult == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); #else /* ! HB_HAS_POLL */ struct timeval tv; fd_set wfds; - # if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerInit( timeout ); # else tv.tv_sec = ( long ) ( timeout / 1000 ); tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; @@ -705,9 +661,6 @@ static int hb_comCanWrite( PHB_COM pCom, HB_MAXINT timeout ) for( ;; ) { - FD_ZERO( &wfds ); - FD_SET( pCom->fd, &wfds ); - if( timeout < 0 ) { tv.tv_sec = 1; @@ -721,28 +674,22 @@ static int hb_comCanWrite( PHB_COM pCom, HB_MAXINT timeout ) } # endif + FD_ZERO( &wfds ); + FD_SET( pCom->fd, &wfds ); iResult = select( ( int ) ( pCom->fd + 1 ), NULL, &wfds, NULL, &tv ); + hb_comSetOsError( pCom, iResult == -1 ); if( iResult > 0 && ! FD_ISSET( pCom->fd, &wfds ) ) iResult = 0; - hb_comSetOsError( pCom, iResult == -1 ); - if( iResult == 0 && timeout < 0 && hb_vmRequestQuery() == 0 ) - continue; - if( iResult != -1 || timeout == 0 || ! HB_COM_IS_EINTR() || + else if( iResult == -1 && HB_COM_IS_EINTR( pCom ) ) + iResult = 0; +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult != 0 || timeout >= 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || hb_vmRequestQuery() != 0 ) break; -# if ! defined( HB_HAS_SELECT_TIMER ) - else if( timeout > 0 ) - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - if( ( timeout -= timecurr - timer ) <= 0 ) - break; - timer = timecurr; - } - } # endif - break; } #endif /* ! HB_HAS_POLL */ @@ -1350,7 +1297,7 @@ long hb_comSend( int iPort, const void * data, long len, HB_MAXINT timeout ) lSent = write( pCom->fd, data, len ); hb_comSetOsError( pCom, lSent == -1 ); } - while( lSent == -1 && HB_COM_IS_EINTR() && hb_vmRequestQuery() == 0 ); + while( lSent == -1 && HB_COM_IS_EINTR( pCom ) && hb_vmRequestQuery() == 0 ); } hb_vmLock(); } @@ -1398,7 +1345,7 @@ long hb_comRecv( int iPort, void * data, long len, HB_MAXINT timeout ) lReceived = read( pCom->fd, ( char * ) data, len ); hb_comSetOsError( pCom, lReceived == -1 ); } - while( lReceived == -1 && HB_COM_IS_EINTR() && hb_vmRequestQuery() == 0 ); + while( lReceived == -1 && HB_COM_IS_EINTR( pCom ) && hb_vmRequestQuery() == 0 ); } hb_vmLock(); } @@ -1581,9 +1528,9 @@ int hb_comClose( int iPort ) iResult = close( pCom->fd ); hb_comSetOsError( pCom, iResult == -1 ); } - while( iResult == -1 && HB_COM_IS_EINTR() && hb_vmRequestQuery() == 0 ); + while( iResult == -1 && HB_COM_IS_EINTR( pCom ) && hb_vmRequestQuery() == 0 ); - if( iResult != -1 || HB_COM_IS_EBADF() ) + if( iResult != -1 || HB_COM_IS_EBADF( pCom ) ) { pCom->fd = ( HB_FHANDLE ) FS_ERROR; pCom->status &= ~HB_COM_OPEN; @@ -3530,7 +3477,7 @@ long hb_comSend( int iPort, const void * data, long len, HB_MAXINT timeout ) if( pCom ) { const char * buffer = ( const char * ) data; - HB_MAXUINT timer = timeout <= 0 ? 0 : ( hb_dateMilliSeconds() + timeout ); + HB_MAXUINT timer = hb_timerInit( timeout ); hb_comSetOsError( pCom, SER_SUCCESS ); lSent = 0; @@ -3556,7 +3503,7 @@ long hb_comSend( int iPort, const void * data, long len, HB_MAXINT timeout ) if( len > 0 ) { - if( timer == 0 || timer < hb_dateMilliSeconds() ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) { if( lSent == 0 ) { @@ -3583,7 +3530,7 @@ long hb_comRecv( int iPort, void * data, long len, HB_MAXINT timeout ) if( pCom ) { char * buffer = ( char * ) data; - HB_MAXUINT timer = timeout <= 0 ? 0 : ( hb_dateMilliSeconds() + timeout ); + HB_MAXUINT timer = hb_timerInit( timeout ); hb_comSetOsError( pCom, SER_SUCCESS ); lReceived = 0; @@ -3606,7 +3553,7 @@ long hb_comRecv( int iPort, void * data, long len, HB_MAXINT timeout ) buffer += iRecv; len -= iRecv; - if( lReceived > 0 || timer == 0 || timer < hb_dateMilliSeconds() ) + if( lReceived > 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) { if( lReceived == 0 ) { @@ -4069,7 +4016,7 @@ long hb_comSend( int iPort, const void * data, long len, HB_MAXINT timeout ) if( pCom ) { const char * buffer = ( const char * ) data; - HB_MAXUINT timer = timeout <= 0 ? 0 : ( hb_dateMilliSeconds() + timeout ); + HB_MAXUINT timer = hb_timerInit( timeout ); hb_comSetOsError( pCom, 0 ); lSent = 0; @@ -4086,7 +4033,7 @@ long hb_comSend( int iPort, const void * data, long len, HB_MAXINT timeout ) { buffer += iSent; len -= iSent; - if( timer == 0 || timer < hb_dateMilliSeconds() ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) { if( lSent == 0 ) { @@ -4115,7 +4062,7 @@ long hb_comRecv( int iPort, void * data, long len, HB_MAXINT timeout ) if( pCom ) { char * buffer = ( char * ) data; - HB_MAXUINT timer = timeout <= 0 ? 0 : ( hb_dateMilliSeconds() + timeout ); + HB_MAXUINT timer = hb_timerInit( timeout ); hb_comSetOsError( pCom, 0 ); lReceived = 0; @@ -4134,7 +4081,7 @@ long hb_comRecv( int iPort, void * data, long len, HB_MAXINT timeout ) } else if( iErr == COM_BUFEMPTY ) { - if( lReceived > 0 || timer == 0 || timer < hb_dateMilliSeconds() ) + if( lReceived > 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) { if( lReceived == 0 ) { diff --git a/src/rtl/hbgtcore.c b/src/rtl/hbgtcore.c index 3123bf7a62..ad2832b9a7 100644 --- a/src/rtl/hbgtcore.c +++ b/src/rtl/hbgtcore.c @@ -2926,7 +2926,8 @@ static int hb_gt_def_InkeyNext( PHB_GT pGT, int iEventMask ) /* Wait for keyboard input */ static int hb_gt_def_InkeyGet( PHB_GT pGT, HB_BOOL fWait, double dSeconds, int iEventMask ) { - HB_MAXUINT end_timer; + HB_MAXUINT timer; + HB_MAXINT timeout; PHB_ITEM pKey; HB_BOOL fPop; int iKey; @@ -2945,10 +2946,8 @@ static int hb_gt_def_InkeyGet( PHB_GT pGT, HB_BOOL fWait, double dSeconds, int i } /* Wait forever ?, Use fixed value 100 for strict Clipper compatibility */ - if( fWait && dSeconds * 100 >= 1 ) - end_timer = hb_dateMilliSeconds() + ( HB_MAXUINT ) ( dSeconds * 1000 ); - else - end_timer = 0; + timeout = ( fWait && dSeconds * 100 >= 1 ) ? ( HB_MAXINT ) ( dSeconds * 1000 ) : -1; + timer = hb_timerInit( timeout ); for( ;; ) { @@ -2969,8 +2968,8 @@ static int hb_gt_def_InkeyGet( PHB_GT pGT, HB_BOOL fWait, double dSeconds, int i } /* immediately break if a VM request is pending. */ - if( ! fWait || hb_vmRequestQuery() != 0 || - ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) + if( ! fWait || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) break; HB_GTSELF_UNLOCK( pGT ); @@ -3298,7 +3297,7 @@ static int hb_gt_def_MouseReadKey( PHB_GT pGT, int iEventMask ) { if( iEventMask & INKEY_LDOWN && HB_GTSELF_MOUSEBUTTONPRESSED( pGT, 0, &iRow, &iCol ) ) { - HB_MAXUINT timer = hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerGet(); if( timer - pGT->nMouseLeftTimer <= ( HB_MAXUINT ) HB_GTSELF_MOUSEGETDOUBLECLICKSPEED( pGT ) ) iKey = K_LDBLCLK; else @@ -3311,7 +3310,7 @@ static int hb_gt_def_MouseReadKey( PHB_GT pGT, int iEventMask ) } else if( iEventMask & INKEY_RDOWN && HB_GTSELF_MOUSEBUTTONPRESSED( pGT, 1, &iRow, &iCol ) ) { - HB_MAXUINT timer = hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerGet(); if( timer - pGT->nMouseRightTimer <= ( HB_MAXUINT ) HB_GTSELF_MOUSEGETDOUBLECLICKSPEED( pGT ) ) iKey = K_RDBLCLK; else @@ -3324,7 +3323,7 @@ static int hb_gt_def_MouseReadKey( PHB_GT pGT, int iEventMask ) } else if( iEventMask & INKEY_MMIDDLE && HB_GTSELF_MOUSEBUTTONPRESSED( pGT, 2, &iRow, &iCol ) ) { - HB_MAXUINT timer = hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerGet(); if( timer - pGT->nMouseMiddleTimer <= ( HB_MAXUINT ) HB_GTSELF_MOUSEGETDOUBLECLICKSPEED( pGT ) ) iKey = K_MDBLCLK; else diff --git a/src/rtl/hblpp.c b/src/rtl/hblpp.c index 78f4fd90d0..db114dd38a 100644 --- a/src/rtl/hblpp.c +++ b/src/rtl/hblpp.c @@ -88,7 +88,7 @@ int hb_lppError( PHB_LPP pSocket ) HB_BOOL hb_lppSend( PHB_LPP pSocket, const void * data, HB_SIZE len, HB_MAXINT timeout ) { - HB_MAXINT nTime = 0; + HB_MAXUINT timer; long lSend; if( ! pSocket->pSendBuffer ) @@ -100,8 +100,7 @@ HB_BOOL hb_lppSend( PHB_LPP pSocket, const void * data, HB_SIZE len, HB_MAXINT t pSocket->nSendPos = 0; } - if( timeout > 0 ) - nTime = ( HB_MAXINT ) hb_dateMilliSeconds() + timeout; + timer = hb_timerInit( timeout ); for( ;; ) { @@ -124,8 +123,7 @@ HB_BOOL hb_lppSend( PHB_LPP pSocket, const void * data, HB_SIZE len, HB_MAXINT t pSocket->iError = 0; return HB_TRUE; } - if( timeout == 0 || - ( timeout > 0 && ( timeout = nTime - ( HB_MAXINT ) hb_dateMilliSeconds() ) <= 0 ) ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; @@ -136,7 +134,7 @@ HB_BOOL hb_lppSend( PHB_LPP pSocket, const void * data, HB_SIZE len, HB_MAXINT t HB_BOOL hb_lppRecv( PHB_LPP pSocket, void ** data, HB_SIZE * len, HB_MAXINT timeout ) { - HB_MAXINT nTime = 0; + HB_MAXUINT timer; long lRecv; if( ! pSocket->pRecvBuffer ) @@ -146,8 +144,7 @@ HB_BOOL hb_lppRecv( PHB_LPP pSocket, void ** data, HB_SIZE * len, HB_MAXINT time pSocket->fRecvHasSize = HB_FALSE; } - if( timeout > 0 ) - nTime = ( HB_MAXINT ) hb_dateMilliSeconds() + timeout; + timer = hb_timerInit( timeout ); for( ;; ) { @@ -218,8 +215,7 @@ HB_BOOL hb_lppRecv( PHB_LPP pSocket, void ** data, HB_SIZE * len, HB_MAXINT time pSocket->iError = 0; return HB_TRUE; } - if( timeout == 0 || - ( timeout > 0 && ( timeout = nTime - ( HB_MAXINT ) hb_dateMilliSeconds() ) <= 0 ) ) + if( ( timeout = hb_timerTest( timeout, &timer ) ) == 0 ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; diff --git a/src/rtl/hbsocket.c b/src/rtl/hbsocket.c index 77589fb13c..82797cd662 100644 --- a/src/rtl/hbsocket.c +++ b/src/rtl/hbsocket.c @@ -1628,17 +1628,17 @@ static int hb_socketTransFlags( int flags ) static int hb_socketSelectRD( HB_SOCKET sd, HB_MAXINT timeout ) { #if defined( HB_HAS_POLL ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); - int iResult, iError, tout; + HB_MAXUINT timer = hb_timerInit( timeout ); struct pollfd fds; + int iResult; fds.fd = sd; fds.events = POLLIN; fds.revents = 0; - for( ;; ) + do { - tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout; + int tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout, iError; iResult = poll( &fds, 1, tout ); iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); if( iResult > 0 && ( fds.revents & POLLIN ) == 0 ) @@ -1655,76 +1655,58 @@ static int hb_socketSelectRD( HB_SOCKET sd, HB_MAXINT timeout ) } } hb_socketSetOsError( iError ); - if( ( ( iResult == 0 && ( timeout < 0 || timeout > 1000 ) ) || - ( iResult == -1 && timeout != 0 && HB_SOCK_IS_EINTR( iError ) ) ) && - hb_vmRequestQuery() == 0 ) - { - if( timeout < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - continue; - } - } - } - } - break; + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; } + while( iResult == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); + return iResult; #else /* ! HB_HAS_POLL */ - struct timeval tv, * ptv; + int iResult; + struct timeval tv; fd_set rfds; - int iResult, iError; - # if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerInit( timeout ); +# else + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; # endif - if( timeout >= 0 ) - { - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - ptv = &tv; - } - else - ptv = NULL; - for( ;; ) { - FD_ZERO( &rfds ); - FD_SET( ( HB_SOCKET_T ) sd, &rfds ); + int iError; - iResult = select( ( int ) ( sd + 1 ), &rfds, NULL, NULL, ptv ); - iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); - hb_socketSetOsError( iError ); - if( iResult == -1 && timeout > 0 && HB_SOCK_IS_EINTR( iError ) && - hb_vmRequestQuery() == 0 ) -# if defined( HB_HAS_SELECT_TIMER ) - continue; -# else + if( timeout < 0 ) { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - continue; - } - } + tv.tv_sec = 1; + tv.tv_usec = 0; + } +# if ! defined( HB_HAS_SELECT_TIMER ) + else + { + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; } # endif - break; + + FD_ZERO( &rfds ); + FD_SET( ( HB_SOCKET_T ) sd, &rfds ); + iResult = select( ( int ) ( sd + 1 ), &rfds, NULL, NULL, &tv ); + iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); + hb_socketSetOsError( iError ); + + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; + +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult != 0 || timeout >= 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; +# endif } return iResult < 0 ? -1 : @@ -1735,17 +1717,17 @@ static int hb_socketSelectRD( HB_SOCKET sd, HB_MAXINT timeout ) static int hb_socketSelectWR( HB_SOCKET sd, HB_MAXINT timeout ) { #if defined( HB_HAS_POLL ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); - int iResult, iError, tout; + HB_MAXUINT timer = hb_timerInit( timeout ); struct pollfd fds; + int iResult; fds.fd = sd; fds.events = POLLOUT; fds.revents = 0; - for( ;; ) + do { - tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout; + int tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout, iError; iResult = poll( &fds, 1, tout ); iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); if( iResult > 0 && ( fds.revents & POLLOUT ) == 0 ) @@ -1767,76 +1749,58 @@ static int hb_socketSelectWR( HB_SOCKET sd, HB_MAXINT timeout ) } } hb_socketSetOsError( iError ); - if( ( ( iResult == 0 && ( timeout < 0 || timeout > 1000 ) ) || - ( iResult == -1 && timeout != 0 && HB_SOCK_IS_EINTR( iError ) ) ) && - hb_vmRequestQuery() == 0 ) - { - if( timeout < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - continue; - } - } - } - } - break; + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; } + while( iResult == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); + return iResult; #else /* ! HB_HAS_POLL */ - struct timeval tv, * ptv; + int iResult; + struct timeval tv; fd_set wfds; - int iResult, iError; - -#if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); -#endif - - if( timeout >= 0 ) - { - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - ptv = &tv; - } - else - ptv = NULL; +# if ! defined( HB_HAS_SELECT_TIMER ) + HB_MAXUINT timer = hb_timerInit( timeout ); +# else + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; +# endif for( ;; ) { + int iError; + + if( timeout < 0 ) + { + tv.tv_sec = 1; + tv.tv_usec = 0; + } +# if ! defined( HB_HAS_SELECT_TIMER ) + else + { + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; + } +# endif + FD_ZERO( &wfds ); FD_SET( ( HB_SOCKET_T ) sd, &wfds ); - - iResult = select( ( int ) ( sd + 1 ), NULL, &wfds, NULL, ptv ); + iResult = select( ( int ) ( sd + 1 ), NULL, &wfds, NULL, &tv ); iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); hb_socketSetOsError( iError ); - if( iResult == -1 && timeout > 0 && HB_SOCK_IS_EINTR( iError ) && - hb_vmRequestQuery() == 0 ) -#if defined( HB_HAS_SELECT_TIMER ) - continue; -#else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - continue; - } - } - } -#endif - break; + + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; + +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult != 0 || timeout >= 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; +# endif } return iResult < 0 ? -1 : @@ -1847,7 +1811,7 @@ static int hb_socketSelectWR( HB_SOCKET sd, HB_MAXINT timeout ) static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) { #if defined( HB_HAS_POLL ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); + HB_MAXUINT timer = hb_timerInit( timeout ); int iResult, iError, tout; struct pollfd fds; @@ -1855,7 +1819,7 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) fds.events = POLLOUT; fds.revents = 0; - for( ;; ) + do { tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout; iResult = poll( &fds, 1, tout ); @@ -1879,28 +1843,12 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) } } hb_socketSetOsError( iError ); - if( ( ( iResult == 0 && ( timeout < 0 || timeout > 1000 ) ) || - ( iResult == -1 && timeout != 0 && HB_SOCK_IS_EINTR( iError ) ) ) && - hb_vmRequestQuery() == 0 ) - { - if( timeout < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - continue; - } - } - } - } - break; + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; } + while( iResult == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); + if( iResult > 0 ) { socklen_t len = sizeof( iError ); @@ -1915,43 +1863,49 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) } return iResult; #else /* ! HB_HAS_POLL */ - struct timeval tv, * ptv; - fd_set wfds, * pefds; - -#if defined( HB_OS_WIN ) - fd_set efds; -#endif int iResult, iError; + struct timeval tv; + fd_set wfds, * pefds; +# if defined( HB_OS_WIN ) + fd_set efds; +# endif socklen_t len; -#if ! defined( HB_HAS_SELECT_TIMER ) - HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); -#endif - - if( timeout >= 0 ) - { - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - ptv = &tv; - } - else - ptv = NULL; +# if ! defined( HB_HAS_SELECT_TIMER ) + HB_MAXUINT timer = hb_timerInit( timeout ); +# else + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; +# endif for( ;; ) { + if( timeout < 0 ) + { + tv.tv_sec = 1; + tv.tv_usec = 0; + } +# if ! defined( HB_HAS_SELECT_TIMER ) + else + { + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; + } +# endif + FD_ZERO( &wfds ); FD_SET( ( HB_SOCKET_T ) sd, &wfds ); -#if defined( HB_OS_WIN ) +# if defined( HB_OS_WIN ) FD_ZERO( &efds ); FD_SET( ( HB_SOCKET_T ) sd, &efds ); pefds = &efds; -#else +# else pefds = NULL; -#endif +# endif - iResult = select( ( int ) ( sd + 1 ), NULL, &wfds, pefds, ptv ); + iResult = select( ( int ) ( sd + 1 ), NULL, &wfds, pefds, &tv ); iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); hb_socketSetOsError( iError ); -#if defined( HB_OS_WIN ) +# if defined( HB_OS_WIN ) if( iResult > 0 && FD_ISSET( ( HB_SOCKET_T ) sd, pefds ) ) { iResult = -1; @@ -1961,27 +1915,18 @@ static int hb_socketSelectWRE( HB_SOCKET sd, HB_MAXINT timeout ) hb_socketSetOsError( iError ); } else -#endif - if( iResult == -1 && timeout > 0 && HB_SOCK_IS_EINTR( iError ) && - hb_vmRequestQuery() == 0 ) -#if defined( HB_HAS_SELECT_TIMER ) - continue; -#else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - continue; - } - } - } -#endif +# endif + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; + +# if defined( HB_HAS_SELECT_TIMER ) + if( iResult != 0 || timeout >= 0 || hb_vmRequestQuery() != 0 ) + break; +# else + if( iResult != 0 || ( timeout = hb_timerTest( timeout, &timer ) ) == 0 || + hb_vmRequestQuery() != 0 ) + break; +# endif break; } #if ! defined( HB_OS_WIN ) @@ -3134,7 +3079,6 @@ int hb_socketSelect( PHB_ITEM pArrayRD, HB_BOOL fSetRD, HB_SOCKET sd; HB_SIZE nLen, nPos, ul; int iResult, iError, tout, iPos, i; - HB_MAXUINT timer; PHB_ITEM pItemSets[ 3 ]; HB_BOOL pSet[ 3 ]; int pEvents[ 3 ]; @@ -3183,39 +3127,22 @@ int hb_socketSelect( PHB_ITEM pArrayRD, HB_BOOL fSetRD, } } - timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); - if( hb_vmRequestQuery() == 0 ) { + HB_MAXUINT timer = hb_timerInit( timeout ); + hb_vmUnlock(); - for( ;; ) + do { tout = timeout < 0 || timeout > 1000 ? 1000 : ( int ) timeout; iResult = poll( pfds, nfds, tout ); iError = iResult >= 0 ? 0 : HB_SOCK_GETERROR(); hb_socketSetOsError( iError ); - if( ( ( iResult == 0 && ( timeout < 0 || timeout > 1000 ) ) || - ( iResult == -1 && timeout != 0 && HB_SOCK_IS_EINTR( iError ) ) ) && - hb_vmRequestQuery() == 0 ) - { - if( timeout < 0 ) - continue; - else - { - HB_MAXUINT timecurr = hb_dateMilliSeconds(); - if( timecurr > timer ) - { - timeout -= timecurr - timer; - if( timeout > 0 ) - { - timer = timecurr; - continue; - } - } - } - } - break; + if( iResult == -1 && HB_SOCK_IS_EINTR( iError ) ) + iResult = 0; } + while( iResult == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); hb_vmLock(); pEvents[ 0 ] |= POLLHUP | POLLPRI; @@ -3260,12 +3187,13 @@ int hb_socketSelect( PHB_ITEM pArrayRD, HB_BOOL fSetRD, return iResult; #else /* ! HB_HAS_POLL */ HB_SOCKET maxsd, sd; - int i, ret; + int i, ret, iError; HB_SIZE nLen, nPos, ul; PHB_ITEM pItemSets[ 3 ]; HB_BOOL pSet[ 3 ]; fd_set fds[ 3 ], * pfds[ 3 ]; - struct timeval tv, * ptv; + struct timeval tv; + HB_MAXUINT timer; if( pFunc == NULL ) pFunc = s_socketSelectCallback; @@ -3277,51 +3205,64 @@ int hb_socketSelect( PHB_ITEM pArrayRD, HB_BOOL fSetRD, pSet[ 1 ] = fSetWR; pSet[ 2 ] = fSetEX; - maxsd = 0; - for( i = 0; i < 3; i++ ) + timer = hb_timerInit( timeout ); + + do { - ret = 0; - nLen = pItemSets[ i ] ? hb_arrayLen( pItemSets[ i ] ) : 0; - if( nLen > 0 ) + maxsd = 0; + for( i = 0; i < 3; i++ ) { - FD_ZERO( &fds[ i ] ); - for( ul = 1; ul <= nLen; ul++ ) + ret = 0; + nLen = pItemSets[ i ] ? hb_arrayLen( pItemSets[ i ] ) : 0; + if( nLen > 0 ) { - sd = pFunc( hb_arrayGetItemPtr( pItemSets[ i ], ul ) ); - if( sd != HB_NO_SOCKET ) + FD_ZERO( &fds[ i ] ); + for( ul = 1; ul <= nLen; ul++ ) { - if( maxsd < sd ) - maxsd = sd; - FD_SET( ( HB_SOCKET_T ) sd, &fds[ i ] ); - ret = 1; + sd = pFunc( hb_arrayGetItemPtr( pItemSets[ i ], ul ) ); + if( sd != HB_NO_SOCKET ) + { + if( maxsd < sd ) + maxsd = sd; + FD_SET( ( HB_SOCKET_T ) sd, &fds[ i ] ); + ret = 1; + } } } + pfds[ i ] = ret ? &fds[ i ] : NULL; } - pfds[ i ] = ret ? &fds[ i ] : NULL; - } - if( timeout >= 0 ) - { - tv.tv_sec = ( long ) ( timeout / 1000 ); - tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; - ptv = &tv; - } - else - ptv = NULL; + if( hb_vmRequestQuery() != 0 ) + { + hb_socketSetError( HB_SOCKET_ERR_INVALIDHANDLE ); + pSet[ 0 ] = pSet[ 1 ] = pSet[ 2 ] = HB_FALSE; + ret = -1; + break; + } + + if( timeout < 0 || timeout >= 1000 ) + { + tv.tv_sec = 1; + tv.tv_usec = 0; + } + else + { + tv.tv_sec = ( long ) ( timeout / 1000 ); + tv.tv_usec = ( long ) ( timeout % 1000 ) * 1000; + } - if( hb_vmRequestQuery() == 0 ) - { hb_vmUnlock(); - ret = select( ( int ) ( maxsd + 1 ), pfds[ 0 ], pfds[ 1 ], pfds[ 2 ], ptv ); - hb_socketSetOsError( ret == -1 ? HB_SOCK_GETERROR() : 0 ); + + ret = select( ( int ) ( maxsd + 1 ), pfds[ 0 ], pfds[ 1 ], pfds[ 2 ], &tv ); + iError = ret >= 0 ? 0 : HB_SOCK_GETERROR(); + hb_socketSetOsError( iError ); + if( ret == -1 && HB_SOCK_IS_EINTR( iError ) ) + ret = 0; + hb_vmLock(); } - else - { - hb_socketSetError( HB_SOCKET_ERR_INVALIDHANDLE ); - pSet[ 0 ] = pSet[ 1 ] = pSet[ 2 ] = HB_FALSE; - ret = -1; - } + while( ret == 0 && ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); for( i = 0; i < 3; i++ ) { diff --git a/src/rtl/idle.c b/src/rtl/idle.c index e029647c81..8a16369939 100644 --- a/src/rtl/idle.c +++ b/src/rtl/idle.c @@ -143,13 +143,15 @@ void hb_idleSleep( double dSeconds ) { if( dSeconds >= 0 ) { - HB_MAXUINT end_timer = hb_dateMilliSeconds() + ( HB_MAXUINT ) ( dSeconds * 1000 ); + HB_MAXINT timeout = dSeconds > 0 ? ( HB_MAXINT ) ( dSeconds * 1000 ) : 0; + HB_MAXUINT timer = hb_timerInit( timeout ); do { hb_idleState(); } - while( hb_dateMilliSeconds() < end_timer && hb_vmRequestQuery() == 0 ); + while( ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && + hb_vmRequestQuery() == 0 ); hb_idleReset(); } diff --git a/src/vm/thread.c b/src/vm/thread.c index b249fa297f..98b1e5371b 100644 --- a/src/vm/thread.c +++ b/src/vm/thread.c @@ -1336,7 +1336,7 @@ static int hb_threadWait( PHB_THREADSTATE * pThreads, int iThreads, HB_MAXUINT timer; if( ulMilliSec != HB_THREAD_INFINITE_WAIT ) - timer = hb_dateMilliSeconds() + ulMilliSec; + timer = hb_timerGet() + ulMilliSec; else timer = 0; #endif @@ -1391,7 +1391,7 @@ static int hb_threadWait( PHB_THREADSTATE * pThreads, int iThreads, # endif if( ! fExit && timer ) { - HB_MAXUINT curr = hb_dateMilliSeconds(); + HB_MAXUINT curr = hb_timerGet(); if( timer <= curr ) fExit = HB_TRUE; else