rsrv: support larger than max. array bytes

This commit is contained in:
Michael Davidsaver
2017-03-13 19:22:56 -04:00
parent b783427bf7
commit 3009f88f64
2 changed files with 79 additions and 32 deletions

View File

@@ -1060,6 +1060,9 @@ void destroy_client ( struct client *client )
else if ( client->send.type == mbtLargeTCP ) {
freeListFree ( rsrvLargeBufFreeListTCP, client->send.buf );
}
else if (client->send.type == mbtHugeTCP ) {
free ( client->send.buf );
}
else {
errlogPrintf ( "CAS: Corrupt send buffer free list type code=%u during client cleanup?\n",
client->send.type );
@@ -1072,6 +1075,9 @@ void destroy_client ( struct client *client )
else if ( client->recv.type == mbtLargeTCP ) {
freeListFree ( rsrvLargeBufFreeListTCP, client->recv.buf );
}
else if (client->recv.type == mbtHugeTCP ) {
free ( client->recv.buf );
}
else {
errlogPrintf ( "CAS: Corrupt recv buffer free list type code=%u during client cleanup?\n",
client->send.type );
@@ -1301,43 +1307,84 @@ void casAttachThreadToClient ( struct client *pClient )
taskwdInsert ( pClient->tid, NULL, NULL );
}
static
void casExpandBuffer ( struct message_buffer *buf, ca_uint32_t size, int sendbuf )
{
char *newbuf = NULL;
unsigned newsize;
enum messageBufferType newtype;
assert (size > MAX_TCP);
if ( size <= buf->maxstk || buf->type == mbtUDP ) return;
/* try to alloc new buffer */
if (size <= MAX_TCP) {
return; /* shouldn't happen */
} else if (size <= rsrvSizeofLargeBufTCP) {
newbuf = freeListCalloc ( rsrvLargeBufFreeListTCP );
newsize = rsrvSizeofLargeBufTCP;
newtype = mbtLargeTCP;
}
#ifndef NO_HUGE
else {
size = ((size-1)|0xfff)+1;
if (buf->type==mbtHugeTCP)
newbuf = realloc (buf->buf, size);
else
newbuf = malloc (size);
newtype = mbtHugeTCP;
newsize = size;
}
#endif
if (newbuf) {
/* copy existing buffer */
if (sendbuf) {
/* send buffer uses [0, stk) */
if (buf->type==mbtHugeTCP) {
/* realloc already copied */
} else {
memcpy ( newbuf, buf->buf, buf->stk );
}
} else {
/* recv buffer uses [stk, cnt) */
unsigned used;
assert ( buf->cnt >= buf->stk );
used = buf->cnt - buf->stk;
/* buf->buf may be the same as newbuf if realloc() used */
memmove ( newbuf, &buf->buf[buf->stk], used );
buf->cnt = used;
buf->stk = 0;
}
/* free existing buffer */
if(buf->type==mbtSmallTCP) {
freeListFree ( rsrvSmallBufFreeListTCP, buf->buf );
} else if(buf->type==mbtLargeTCP) {
freeListFree ( rsrvLargeBufFreeListTCP, buf->buf );
} else {
/* realloc() already free()'d if necessary */
}
buf->buf = newbuf;
buf->type = newtype;
buf->maxstk = newsize;
}
}
void casExpandSendBuffer ( struct client *pClient, ca_uint32_t size )
{
if ( pClient->send.type == mbtSmallTCP && rsrvSizeofLargeBufTCP > MAX_TCP
&& size <= rsrvSizeofLargeBufTCP ) {
int spaceAvailOnFreeList = freeListItemsAvail ( rsrvLargeBufFreeListTCP ) > 0;
if ( osiSufficentSpaceInPool(rsrvSizeofLargeBufTCP) || spaceAvailOnFreeList ) {
char *pNewBuf = ( char * ) freeListCalloc ( rsrvLargeBufFreeListTCP );
if ( pNewBuf ) {
memcpy ( pNewBuf, pClient->send.buf, pClient->send.stk );
freeListFree ( rsrvSmallBufFreeListTCP, pClient->send.buf );
pClient->send.buf = pNewBuf;
pClient->send.maxstk = rsrvSizeofLargeBufTCP;
pClient->send.type = mbtLargeTCP;
}
}
}
casExpandBuffer (&pClient->send, size, 1);
}
void casExpandRecvBuffer ( struct client *pClient, ca_uint32_t size )
{
if ( pClient->recv.type == mbtSmallTCP && rsrvSizeofLargeBufTCP > MAX_TCP
&& size <= rsrvSizeofLargeBufTCP) {
int spaceAvailOnFreeList = freeListItemsAvail ( rsrvLargeBufFreeListTCP ) > 0;
if ( osiSufficentSpaceInPool(rsrvSizeofLargeBufTCP) || spaceAvailOnFreeList ) {
char *pNewBuf = ( char * ) freeListCalloc ( rsrvLargeBufFreeListTCP );
if ( pNewBuf ) {
assert ( pClient->recv.cnt >= pClient->recv.stk );
memcpy ( pNewBuf, &pClient->recv.buf[pClient->recv.stk], pClient->recv.cnt - pClient->recv.stk );
freeListFree ( rsrvSmallBufFreeListTCP, pClient->recv.buf );
pClient->recv.buf = pNewBuf;
pClient->recv.cnt = pClient->recv.cnt - pClient->recv.stk;
pClient->recv.stk = 0u;
pClient->recv.maxstk = rsrvSizeofLargeBufTCP;
pClient->recv.type = mbtLargeTCP;
}
}
}
casExpandBuffer (&pClient->recv, size, 0);
}
/*

View File

@@ -60,7 +60,7 @@ typedef struct caHdrLargeArray {
* Eight-byte alignment is required by the Sparc 5 and other RISC
* processors.
*/
enum messageBufferType { mbtUDP, mbtSmallTCP, mbtLargeTCP };
enum messageBufferType { mbtUDP, mbtSmallTCP, mbtLargeTCP, mbtHugeTCP };
struct message_buffer {
char *buf;
unsigned stk;