From 4e02eab09f8324b1422f051a1303836def22ee43 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Thu, 7 Jan 2010 13:07:54 +0000 Subject: [PATCH] 2010-01-07 14:07 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/rtl/hbznet.c * harbour/include/hbznet.h * added new optional parameter to hb_znetWrite() function which allow to catch result of last hb_socketSend() operation * removed automatic flushing from hb_znetWrite() function, it should help in implementing more efficient C code using hb_znet*() functions * harbour/src/rtl/hbinet.c * flush HB_ZNETSTREAM output after write operation % small optimization in internal inet error setting --- harbour/ChangeLog | 13 ++++++++++ harbour/include/hbznet.h | 4 ++-- harbour/src/rtl/hbinet.c | 51 +++++++++++++++++++++++++--------------- harbour/src/rtl/hbznet.c | 43 +++++++++++++++++++-------------- 4 files changed, 72 insertions(+), 39 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index af68aa4b0b..89b64e68ba 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,19 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-07 14:07 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/rtl/hbznet.c + * harbour/include/hbznet.h + * added new optional parameter to hb_znetWrite() function which allow + to catch result of last hb_socketSend() operation + * removed automatic flushing from hb_znetWrite() function, + it should help in implementing more efficient C code using + hb_znet*() functions + + * harbour/src/rtl/hbinet.c + * flush HB_ZNETSTREAM output after write operation + % small optimization in internal inet error setting + 2010-01-07 10:53 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * ChangeLog * Some changes marked DONE. diff --git a/harbour/include/hbznet.h b/harbour/include/hbznet.h index 4c039d26f9..34e13f5f52 100644 --- a/harbour/include/hbznet.h +++ b/harbour/include/hbznet.h @@ -64,7 +64,7 @@ HB_EXTERN_BEGIN typedef void * PHB_ZNETSTREAM; #endif -typedef long ( * HB_INET_SFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, const void *, long, HB_LONG ); +typedef long ( * HB_INET_SFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, const void *, long, HB_LONG, long * ); typedef long ( * HB_INET_RFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, void *, long, HB_LONG ); typedef long ( * HB_INET_FFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, HB_LONG ); typedef void ( * HB_INET_CFUNC ) ( PHB_ZNETSTREAM ); @@ -76,7 +76,7 @@ extern HB_EXPORT void hb_znetClose( PHB_ZNETSTREAM pStream ); extern HB_EXPORT int hb_znetError( PHB_ZNETSTREAM pStream ); extern HB_EXPORT long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len, HB_LONG timeout ); extern HB_EXPORT long hb_znetFlush( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout ); -extern HB_EXPORT long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_LONG timeout ); +extern HB_EXPORT long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_LONG timeout, long * plast ); extern HB_EXPORT BOOL hb_znetInetInitialize( PHB_ITEM, PHB_ZNETSTREAM, HB_INET_RFUNC, diff --git a/harbour/src/rtl/hbinet.c b/harbour/src/rtl/hbinet.c index 6478f62f05..fdef1627ab 100644 --- a/harbour/src/rtl/hbinet.c +++ b/harbour/src/rtl/hbinet.c @@ -723,10 +723,9 @@ static void s_inetRecvInternal( int iMode ) socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iLen < 0 ) { - if( hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) + socket->iError = hb_socketGetError(); + if( socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; - else - socket->iError = hb_socketGetError(); } hb_retni( iReceived > 0 ? iReceived : iLen ); } @@ -841,10 +840,9 @@ static void s_inetRecvPattern( const char ** patterns, int * patternsizes, socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iLen < 0 ) { - if( hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) + socket->iError = hb_socketGetError(); + if( socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; - else - socket->iError = hb_socketGetError(); } else { @@ -965,6 +963,7 @@ static void s_inetSendInternal( BOOL lAll ) PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); const char * buffer; int iLen, iSent, iSend; + long lLastSnd = 1; if( socket == NULL || pBuffer == NULL ) hb_inetErrRT(); @@ -987,9 +986,16 @@ static void s_inetSendInternal( BOOL lAll ) while( iSent < iSend ) { if( socket->sendFunc ) + { iLen = socket->sendFunc( socket->stream, socket->sd, buffer + iSent, iSend - iSent, - socket->iTimeout ); + socket->iTimeout, &lLastSnd ); + if( lLastSnd <= 0 && iLen > 0 ) + { + iSent += iLen; + iLen = ( int ) lLastSnd; + } + } else iLen = hb_socketSend( socket->sd, buffer + iSent, iSend - iSent, 0, socket->iTimeout ); @@ -1001,14 +1007,24 @@ static void s_inetSendInternal( BOOL lAll ) } else { - if( iLen == -1 && hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) + socket->iError = hb_socketGetError(); + if( iLen == -1 && socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; - else - socket->iError = hb_socketGetError(); break; } } socket->iCount = iSent; + + if( socket->flushFunc && ( lLastSnd > 0 || ( lLastSnd == -1 && + socket->iTimeout >= 0 && socket->iTimeout < 10000 && + hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) ) ) + { + /* TODO: safe information about unflushed data and try to call + flush before entering receive wait sate */ + socket->flushFunc( socket->stream, socket->sd, socket->iTimeout < 0 ? + socket->iTimeout : HB_MAX( socket->iTimeout, 10000 ) ); + } + hb_retni( iSent > 0 ? iSent : iLen ); } } @@ -1127,10 +1143,9 @@ HB_FUNC( HB_INETACCEPT ) if( incoming == HB_NO_SOCKET ) { - if( hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) + socket->iError = hb_socketGetError(); + if( socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; - else - socket->iError = hb_socketGetError(); } else { @@ -1331,10 +1346,9 @@ HB_FUNC( HB_INETDGRAMSEND ) socket->iTimeout ); if( iLen == -1 ) { - if( hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) + socket->iError = hb_socketGetError(); + if( socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; - else - socket->iError = hb_socketGetError(); } else { @@ -1398,10 +1412,9 @@ HB_FUNC( HB_INETDGRAMRECV ) socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iMax < 0 ) { - if( hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) + socket->iError = hb_socketGetError(); + if( socket->iError == HB_SOCKET_ERR_TIMEOUT ) socket->iError = HB_INET_ERR_TIMEOUT; - else - socket->iError = hb_socketGetError(); } else socket->iError = HB_INET_ERR_OK; diff --git a/harbour/src/rtl/hbznet.c b/harbour/src/rtl/hbznet.c index 091341b1b7..9233dafb16 100644 --- a/harbour/src/rtl/hbznet.c +++ b/harbour/src/rtl/hbznet.c @@ -159,6 +159,25 @@ long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len, return len == 0 ? rec : len; } +static long hb_znetStreamWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout ) +{ + long tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out; + long snd = 0; + + if( tosnd > 0 ) + { + snd = hb_socketSend( sd, pStream->outbuf, tosnd, 0, timeout ); + if( snd > 0 ) + { + if( snd < tosnd ) + memmove( pStream->outbuf, pStream->outbuf + snd, tosnd - snd ); + pStream->wr.avail_out += ( uInt ) snd; + pStream->wr.next_out = pStream->outbuf + tosnd - snd; + } + } + return snd; +} + /* flush data in stream structure - return number of bytes left in the * buffer which were not sent */ @@ -171,14 +190,8 @@ long hb_znetFlush( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout ) while( pStream->wr.avail_out < HB_ZNET_BUFSIZE ) { - long tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out; - long snd = hb_socketSend( sd, pStream->outbuf, tosnd, 0, timeout ); - if( snd <= 0 ) + if( hb_znetStreamWrite( pStream, sd, timeout ) <= 0 ) break; - if( snd < tosnd ) - memmove( pStream->outbuf, pStream->outbuf + snd, tosnd - snd ); - pStream->wr.avail_out += ( uInt ) snd; - pStream->wr.next_out = pStream->outbuf + tosnd - snd; if( pStream->err == Z_OK ) pStream->err = deflate( &pStream->wr, Z_SYNC_FLUSH ); @@ -189,7 +202,7 @@ long hb_znetFlush( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout ) /* write data using stream structure */ -long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_LONG timeout ) +long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_LONG timeout, long * plast ) { long snd = 0; @@ -201,13 +214,11 @@ long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, lo { if( pStream->wr.avail_out == 0 ) { - snd = hb_socketSend( sd, pStream->outbuf, HB_ZNET_BUFSIZE, 0, timeout ); + snd = hb_znetStreamWrite( pStream, sd, timeout ); + if( plast ) + *plast = snd; if( snd <= 0 ) break; - if( snd < HB_ZNET_BUFSIZE ) - memmove( pStream->outbuf, pStream->outbuf + snd, HB_ZNET_BUFSIZE - snd ); - pStream->wr.avail_out += ( uInt ) snd; - pStream->wr.next_out = pStream->outbuf + HB_ZNET_BUFSIZE - snd; snd = 0; } pStream->err = deflate( &pStream->wr, Z_NO_FLUSH ); @@ -215,10 +226,6 @@ long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, lo break; } - if( pStream->wr.avail_in == 0 || ( timeout >= 0 && timeout < 10000 && - ( pStream->err == Z_OK || pStream->err == Z_STREAM_END ) ) ) - hb_znetFlush( pStream, sd, timeout < 0 ? timeout : HB_MAX( timeout, 10000 ) ); - len -= pStream->wr.avail_in; return len == 0 ? snd : len; @@ -255,7 +262,7 @@ HB_FUNC( HB_INETCOMPRESS ) { PHB_ZNETSTREAM pStream = hb_znetOpen( iLevel, iStrategy ); if( pStream == NULL ) - pItem = NULL; + pItem = NULL; /* to force RTE */ if( ! hb_znetInetInitialize( pItem, pStream, hb_znetRead, hb_znetWrite, hb_znetFlush, hb_znetClose ) ) {