From 85b6b5c50750b61c54a53cb2b019cf0f5cd552da Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 13 Mar 2017 19:22:50 -0400 Subject: [PATCH] ca: support alloc larger than max array bytes automatically try to allocate a custom buffer when a message larger than ca max array bytes is encountered. --- src/ca/client/tcpiiu.cpp | 62 ++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/ca/client/tcpiiu.cpp b/src/ca/client/tcpiiu.cpp index 7fd848b20..9581baa4c 100644 --- a/src/ca/client/tcpiiu.cpp +++ b/src/ca/client/tcpiiu.cpp @@ -26,6 +26,9 @@ #include #include + +#include + #include "errlog.h" #define epicsExportSharedSymbols @@ -1023,12 +1026,15 @@ tcpiiu :: ~tcpiiu () // free message body cache if ( this->pCurData ) { - if ( this->curDataMax == MAX_TCP ) { + if ( this->curDataMax <= MAX_TCP ) { this->cacRef.releaseSmallBufferTCP ( this->pCurData ); } - else { + else if ( this->curDataMax <= cacRef.largeBufferSizeTCP()) { this->cacRef.releaseLargeBufferTCP ( this->pCurData ); } + else { + free ( this->pCurData ); + } } } @@ -1197,18 +1203,44 @@ bool tcpiiu::processIncoming ( // make sure we have a large enough message body cache // if ( this->curMsg.m_postsize > this->curDataMax ) { - if ( this->curDataMax == MAX_TCP && - this->cacRef.largeBufferSizeTCP() >= this->curMsg.m_postsize ) { - char * pBuf = this->cacRef.allocateLargeBufferTCP (); - if ( pBuf ) { + assert (this->curMsg.m_postsize > MAX_TCP); + + char * newbuf = NULL; + arrayElementCount newsize; + + if ( this->curMsg.m_postsize <= this->cacRef.largeBufferSizeTCP() ) { + newbuf = this->cacRef.allocateLargeBufferTCP (); + newsize = this->cacRef.largeBufferSizeTCP(); + } +#ifndef NO_HUGE + else { + // round size up to multiple of 4K + newsize = ((this->curMsg.m_postsize-1)|0xfff)+1; + + if (this->curDataMax > this->cacRef.largeBufferSizeTCP()) { + // expand existing huge buffer + newbuf = (char*)realloc(this->pCurData, newsize); + } else { + // trade up from small or large + newbuf = (char*)malloc(newsize); + } + } +#endif + + if ( newbuf) { + if (this->curDataMax <= MAX_TCP) { this->cacRef.releaseSmallBufferTCP ( this->pCurData ); - this->pCurData = pBuf; - this->curDataMax = this->cacRef.largeBufferSizeTCP (); - } - else { - this->printFormated ( mgr.cbGuard, - "CAC: not enough memory for message body cache (ignoring response message)\n"); + } else if (this->curDataMax <= this->cacRef.largeBufferSizeTCP()) { + this->cacRef.releaseLargeBufferTCP ( this->pCurData ); + } else { + // called realloc() } + this->pCurData = newbuf; + this->curDataMax = newsize; + + } else { + this->printFormated ( mgr.cbGuard, + "CAC: not enough memory for message body cache (ignoring response message)\n"); } } @@ -1426,7 +1458,7 @@ void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, } arrayElementCount maxBytes; if ( CA_V49 ( this->minorProtocolVersion ) ) { - maxBytes = this->cacRef.largeBufferSizeTCP (); + maxBytes = 0xfffffff0; } else { maxBytes = MAX_TCP; @@ -1537,7 +1569,7 @@ void tcpiiu::subscriptionRequest ( guard, CA_V413(this->minorProtocolVersion) ); arrayElementCount maxBytes; if ( CA_V49 ( this->minorProtocolVersion ) ) { - maxBytes = this->cacRef.largeBufferSizeTCP (); + maxBytes = 0xfffffff0; } else { maxBytes = MAX_TCP; @@ -1584,7 +1616,7 @@ void tcpiiu::subscriptionUpdateRequest ( guard, CA_V413(this->minorProtocolVersion) ); arrayElementCount maxBytes; if ( CA_V49 ( this->minorProtocolVersion ) ) { - maxBytes = this->cacRef.largeBufferSizeTCP (); + maxBytes = 0xfffffff0; } else { maxBytes = MAX_TCP;