From e150da6f935a85b44bf8d97bd56f7b7d7a150b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Fri, 14 Apr 2017 16:36:50 +0200 Subject: [PATCH] 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 --- ChangeLog.txt | 78 ++++++ contrib/hbnetio/netiosrv.c | 35 +-- contrib/hbssl/ssl_sock.c | 38 +-- contrib/xhb/hboutdbg.c | 13 +- include/hbapifs.h | 25 ++ include/hbdate.h | 4 + src/3rd/hbdossrl/serial.c | 4 +- src/common/hbdate.c | 33 +++ src/harbour.def | 4 + src/rtl/filesys.c | 544 +++++++++++++++++++++++-------------- src/rtl/gtcrs/gtcrs.c | 97 ++++--- src/rtl/gtcrs/gtcrs.h | 2 + src/rtl/gtpca/gtpca.c | 38 +-- src/rtl/gtsln/gtsln.c | 22 +- src/rtl/gtsln/mousesln.c | 11 +- src/rtl/gtstd/gtstd.c | 16 +- src/rtl/gttrm/gttrm.c | 107 +++----- src/rtl/gtwin/gtwin.c | 6 +- src/rtl/gtxwc/gtxwc.c | 20 +- src/rtl/hbcom.c | 151 ++++------ src/rtl/hbgtcore.c | 19 +- src/rtl/hblpp.c | 16 +- src/rtl/hbsocket.c | 443 +++++++++++++----------------- src/rtl/idle.c | 6 +- src/vm/thread.c | 4 +- 25 files changed, 901 insertions(+), 835 deletions(-) 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