fixed enobuf causes stuck send thread

This commit is contained in:
Jeff Hill
2004-02-05 21:12:09 +00:00
parent 7ad5347f7f
commit 4e1fd091ea
2 changed files with 99 additions and 46 deletions

View File

@@ -245,7 +245,7 @@ FAST int sock;
UNLOCK_CLIENTQ;
client->recv.cnt = 0ul;
while (TRUE) {
while ( ! client->disconnect ) {
client->recv.stk = 0;
nchars = recv(
@@ -269,6 +269,15 @@ FAST int sock;
long anerrno;
anerrno = errnoGet();
if ( anerrno == SOCK_ENOBUFS ) {
logMsg (
"rsrv: system low on network buffers "
"- receive retry in 15 seconds\n",
0,0,0,0,0,0 );
taskDelay ( 15 * sysClkRateGet() );
continue;
}
/*
* normal conn lost conditions

View File

@@ -61,6 +61,7 @@ int lock_needed;
}
if(pclient->disconnect){
pclient->send.stk = 0;
if(CASDEBUG>2){
logMsg( "CAS: msg Discard for sock %d addr %x\n",
pclient->sock,
@@ -77,46 +78,49 @@ int lock_needed;
SEND_LOCK(pclient);
}
if(pclient->send.stk){
#ifdef CONVERSION_REQUIRED
/* Convert all caHdr into net format.
* The remaining bytes must already be in
* net format, because here we have no clue
* how to convert them.
*/
char *buf;
unsigned long msg_size, num_bytes;
caHdr *mp;
{
/* Convert all caHdr into net format.
* The remaining bytes must already be in
* net format, because here we have no clue
* how to convert them.
*/
char * buf;
unsigned long msg_size, num_bytes;
caHdr * mp;
buf = (char *) pclient->send.buf;
num_bytes = pclient->send.stk;
buf = (char *) pclient->send.buf;
num_bytes = pclient->send.stk;
/* convert only if we have at least a complete caHdr */
while (num_bytes >= sizeof(caHdr))
{
mp = (caHdr *) buf;
/* convert only if we have at least a complete caHdr */
while (num_bytes >= sizeof(caHdr))
{
mp = (caHdr *) buf;
msg_size = sizeof (caHdr) + mp->m_postsize;
msg_size = sizeof (caHdr) + mp->m_postsize;
DLOG(3,"CAS: sending cmmd %d, postsize %d\n",
mp->m_cmmd, (int)mp->m_postsize,
0, 0, 0, 0);
DLOG(3,"CAS: sending cmmd %d, postsize %d\n",
mp->m_cmmd, (int)mp->m_postsize,
0, 0, 0, 0);
/* convert the complete header into host format */
mp->m_cmmd = htons (mp->m_cmmd);
mp->m_postsize = htons (mp->m_postsize);
mp->m_dataType = htons (mp->m_dataType);
mp->m_count = htons (mp->m_count);
mp->m_cid = htonl (mp->m_cid);
mp->m_available = htonl (mp->m_available);
/* convert the complete header into host format */
mp->m_cmmd = htons (mp->m_cmmd);
mp->m_postsize = htons (mp->m_postsize);
mp->m_dataType = htons (mp->m_dataType);
mp->m_count = htons (mp->m_count);
mp->m_cid = htonl (mp->m_cid);
mp->m_available = htonl (mp->m_available);
/* get next message: */
buf += msg_size;
num_bytes -= msg_size;
}
/* get next message: */
buf += msg_size;
num_bytes -= msg_size;
}
}
#endif
while(pclient->send.stk&&!pclient->disconnect){
status = sendto(
pclient->sock,
pclient->send.buf,
@@ -124,16 +128,34 @@ int lock_needed;
NULL,
(struct sockaddr *)&pclient->addr,
sizeof(pclient->addr));
if( pclient->send.stk != (unsigned)status){
if( pclient->send.stk == (unsigned)status){
pclient->send.stk = 0;
pclient->ticks_at_last_send = tickGet();
}
else {
if(status < 0){
int anerrno;
char buf[64];
anerrno = errnoGet();
if ( pclient->disconnect ) {
pclient->send.stk = 0;
break;
}
ipAddrToA (&pclient->addr, buf, sizeof(buf));
if(pclient->proto == IPPROTO_TCP) {
if ( anerrno == ENOBUFS ) {
logMsg (
"rsrv: system low on network buffers - "
"tcp send retry in 15 sec\n",
0,0,0,0,0,0);
taskDelay ( 15 * sysClkRateGet() );
continue;
}
if( (anerrno!=ECONNABORTED&&
anerrno!=ECONNRESET&&
anerrno!=EPIPE&&
@@ -149,7 +171,19 @@ int lock_needed;
NULL,
NULL);
}
pclient->send.stk = 0;
pclient->disconnect = TRUE;
{
static const int shutdownReadAndWrite = 2;
int status = shutdown ( pclient->sock, shutdownReadAndWrite );
if ( status ) {
logMsg (
"rsrv: socket shutdown error was %s\n",
(int) strerror ( anerrno ), NULL, NULL,
NULL, NULL, NULL );
}
}
break;
}
else if (pclient->proto == IPPROTO_UDP) {
if (anerrno==ENOBUFS) {
@@ -165,29 +199,39 @@ int lock_needed;
NULL,
NULL);
}
break;
}
else {
assert (0);
}
}
else{
logMsg(
"CAS: blk sock partial send: req %d sent %d \n",
pclient->send.stk,
status,
NULL,
NULL,
NULL,
NULL);
pclient->ticks_at_last_send = tickGet();
if(pclient->proto == IPPROTO_TCP) {
unsigned transferSize = (unsigned) status;
if ( pclient->send.stk > transferSize ) {
unsigned bytesLeft = pclient->send.stk - transferSize;
memmove ( pclient->send.buf, &pclient->send.buf[transferSize],
bytesLeft );
pclient->send.stk = bytesLeft;
}
else {
pclient->send.stk = 0;
}
}
else if (pclient->proto == IPPROTO_UDP) {
pclient->send.stk = 0;
logMsg ( "partial UDP message sent?\n",
0,0,0,0,0,0);
break;
}
else {
assert ( 0 );
}
}
}
pclient->send.stk = 0;
pclient->ticks_at_last_send = tickGet();
}
if(lock_needed){
SEND_UNLOCK(pclient);
}