fixed enobuf causes stuck send thread
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user