ca: large array free list is optional
This commit is contained in:
@@ -54,6 +54,12 @@ static const char pVersionCAC[] =
|
||||
"@(#) " EPICS_VERSION_STRING
|
||||
", CA Client Library " __DATE__;
|
||||
|
||||
// when set, respect EPICS_CA_MAX_ARRAY_BYTES
|
||||
// when clear, ignore it
|
||||
extern "C" {
|
||||
int caLimitArray;
|
||||
}
|
||||
|
||||
// TCP response dispatch table
|
||||
const cac::pProtoStubTCP cac::tcpJumpTableCAC [] =
|
||||
{
|
||||
@@ -218,9 +224,11 @@ cac::cac (
|
||||
throw std::bad_alloc ();
|
||||
}
|
||||
|
||||
freeListInitPvt ( &this->tcpLargeRecvBufFreeList, this->maxRecvBytesTCP, 1 );
|
||||
if ( ! this->tcpLargeRecvBufFreeList ) {
|
||||
throw std::bad_alloc ();
|
||||
if(caLimitArray) {
|
||||
freeListInitPvt ( &this->tcpLargeRecvBufFreeList, this->maxRecvBytesTCP, 1 );
|
||||
if ( ! this->tcpLargeRecvBufFreeList ) {
|
||||
throw std::bad_alloc ();
|
||||
}
|
||||
}
|
||||
unsigned bufsPerArray = this->maxRecvBytesTCP / comBuf::capacityBytes ();
|
||||
if ( bufsPerArray > 1u ) {
|
||||
@@ -231,9 +239,7 @@ cac::cac (
|
||||
catch ( ... ) {
|
||||
osiSockRelease ();
|
||||
delete [] this->pUserName;
|
||||
if ( this->tcpSmallRecvBufFreeList ) {
|
||||
freeListCleanup ( this->tcpSmallRecvBufFreeList );
|
||||
}
|
||||
freeListCleanup ( this->tcpSmallRecvBufFreeList );
|
||||
if ( this->tcpLargeRecvBufFreeList ) {
|
||||
freeListCleanup ( this->tcpLargeRecvBufFreeList );
|
||||
}
|
||||
@@ -318,7 +324,9 @@ cac::~cac ()
|
||||
}
|
||||
|
||||
freeListCleanup ( this->tcpSmallRecvBufFreeList );
|
||||
freeListCleanup ( this->tcpLargeRecvBufFreeList );
|
||||
if ( this->tcpLargeRecvBufFreeList ) {
|
||||
freeListCleanup ( this->tcpLargeRecvBufFreeList );
|
||||
}
|
||||
|
||||
delete [] this->pUserName;
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
class netWriteNotifyIO;
|
||||
class netReadNotifyIO;
|
||||
class netSubscription;
|
||||
class tcpiiu;
|
||||
|
||||
// used to control access to cac's recycle routines which
|
||||
// should only be indirectly invoked by CAC when its lock
|
||||
@@ -193,12 +194,6 @@ public:
|
||||
const char *pformat, va_list args ) const;
|
||||
double connectionTimeout ( epicsGuard < epicsMutex > & );
|
||||
|
||||
// buffer management
|
||||
char * allocateSmallBufferTCP ();
|
||||
void releaseSmallBufferTCP ( char * );
|
||||
unsigned largeBufferSizeTCP () const;
|
||||
char * allocateLargeBufferTCP ();
|
||||
void releaseLargeBufferTCP ( char * );
|
||||
unsigned maxContiguousFrames ( epicsGuard < epicsMutex > & ) const;
|
||||
|
||||
// misc
|
||||
@@ -355,6 +350,8 @@ private:
|
||||
|
||||
cac ( const cac & );
|
||||
cac & operator = ( const cac & );
|
||||
|
||||
friend class tcpiiu;
|
||||
};
|
||||
|
||||
inline const char * cac::userNamePointer () const
|
||||
@@ -385,35 +382,6 @@ inline void cac::attachToClientCtx ()
|
||||
this->notify.attachToClientCtx ();
|
||||
}
|
||||
|
||||
inline char * cac::allocateSmallBufferTCP ()
|
||||
{
|
||||
// this locks internally
|
||||
return ( char * ) freeListMalloc ( this->tcpSmallRecvBufFreeList );
|
||||
}
|
||||
|
||||
inline void cac::releaseSmallBufferTCP ( char *pBuf )
|
||||
{
|
||||
// this locks internally
|
||||
freeListFree ( this->tcpSmallRecvBufFreeList, pBuf );
|
||||
}
|
||||
|
||||
inline unsigned cac::largeBufferSizeTCP () const
|
||||
{
|
||||
return this->maxRecvBytesTCP;
|
||||
}
|
||||
|
||||
inline char * cac::allocateLargeBufferTCP ()
|
||||
{
|
||||
// this locks internally
|
||||
return ( char * ) freeListMalloc ( this->tcpLargeRecvBufFreeList );
|
||||
}
|
||||
|
||||
inline void cac::releaseLargeBufferTCP ( char *pBuf )
|
||||
{
|
||||
// this locks internally
|
||||
freeListFree ( this->tcpLargeRecvBufFreeList, pBuf );
|
||||
}
|
||||
|
||||
inline unsigned cac::beaconAnomaliesSinceProgramStart (
|
||||
epicsGuard < epicsMutex > & guard ) const
|
||||
{
|
||||
|
||||
@@ -690,7 +690,7 @@ tcpiiu::tcpiiu (
|
||||
curDataBytes ( 0ul ),
|
||||
comBufMemMgr ( comBufMemMgrIn ),
|
||||
cacRef ( cac ),
|
||||
pCurData ( cac.allocateSmallBufferTCP () ),
|
||||
pCurData ( (char*) freeListMalloc(this->cacRef.tcpSmallRecvBufFreeList) ),
|
||||
pSearchDest ( pSearchDestIn ),
|
||||
mutex ( mutexIn ),
|
||||
cbMutex ( cbMutexIn ),
|
||||
@@ -714,9 +714,12 @@ tcpiiu::tcpiiu (
|
||||
socketHasBeenClosed ( false ),
|
||||
unresponsiveCircuit ( false )
|
||||
{
|
||||
if(!pCurData)
|
||||
throw std::bad_alloc();
|
||||
|
||||
this->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
|
||||
if ( this->sock == INVALID_SOCKET ) {
|
||||
cac.releaseSmallBufferTCP ( this->pCurData );
|
||||
freeListFree(this->cacRef.tcpSmallRecvBufFreeList, this->pCurData);
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
@@ -1027,10 +1030,10 @@ tcpiiu :: ~tcpiiu ()
|
||||
// free message body cache
|
||||
if ( this->pCurData ) {
|
||||
if ( this->curDataMax <= MAX_TCP ) {
|
||||
this->cacRef.releaseSmallBufferTCP ( this->pCurData );
|
||||
freeListFree(this->cacRef.tcpSmallRecvBufFreeList, this->pCurData);
|
||||
}
|
||||
else if ( this->curDataMax <= cacRef.largeBufferSizeTCP()) {
|
||||
this->cacRef.releaseLargeBufferTCP ( this->pCurData );
|
||||
else if ( this->cacRef.tcpLargeRecvBufFreeList ) {
|
||||
freeListFree(this->cacRef.tcpLargeRecvBufFreeList, this->pCurData);
|
||||
}
|
||||
else {
|
||||
free ( this->pCurData );
|
||||
@@ -1208,30 +1211,32 @@ bool tcpiiu::processIncoming (
|
||||
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 {
|
||||
if ( !this->cacRef.tcpLargeRecvBufFreeList ) {
|
||||
// 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
|
||||
if ( this->curDataMax <= MAX_TCP ) {
|
||||
// small -> large
|
||||
newbuf = (char*)malloc(newsize);
|
||||
|
||||
} else {
|
||||
// expand large to larger
|
||||
newbuf = (char*)realloc(this->pCurData, newsize);
|
||||
}
|
||||
|
||||
} else if ( this->curMsg.m_postsize <= this->cacRef.maxRecvBytesTCP ) {
|
||||
newbuf = (char*) freeListMalloc(this->cacRef.tcpLargeRecvBufFreeList);
|
||||
newsize = this->cacRef.maxRecvBytesTCP;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( newbuf) {
|
||||
if (this->curDataMax <= MAX_TCP) {
|
||||
this->cacRef.releaseSmallBufferTCP ( this->pCurData );
|
||||
} else if (this->curDataMax <= this->cacRef.largeBufferSizeTCP()) {
|
||||
this->cacRef.releaseLargeBufferTCP ( this->pCurData );
|
||||
freeListFree(this->cacRef.tcpSmallRecvBufFreeList, this->pCurData );
|
||||
|
||||
} else if (this->cacRef.tcpLargeRecvBufFreeList) {
|
||||
freeListFree(this->cacRef.tcpLargeRecvBufFreeList, this->pCurData );
|
||||
|
||||
} else {
|
||||
// called realloc()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user