check for shutdown condition when socket sys call returns EINTR

This commit is contained in:
Jeff Hill
2000-06-13 22:33:27 +00:00
parent 78b8324a8d
commit 889e03fa83
3 changed files with 73 additions and 63 deletions

View File

@@ -442,7 +442,7 @@ public:
unsigned short repeaterPort;
bool contactRepeater;
bool repeaterContacted;
bool sendThreadExitCmd;
bool shutdownCmd;
// exceptions
class noSocket {};
@@ -503,6 +503,7 @@ public:
int post_msg (char *pInBuf, unsigned long blockSize);
void addToChanList (nciu *chan);
void removeFromChanList (nciu *chan);
void connect ();
void disconnect (nciu *chan);
bool fullyConstructed () const;
void recvMsg ();

View File

@@ -84,9 +84,9 @@ tcpiiu * constructTCPIIU (cac *pcac, const struct sockaddr_in *pina,
/*
* cac_connect_tcp ()
* tcpiiu::connect ()
*/
LOCAL void cac_connect_tcp (tcpiiu *piiu)
void tcpiiu::connect ()
{
int status;
@@ -96,14 +96,14 @@ LOCAL void cac_connect_tcp (tcpiiu *piiu)
while (1) {
int errnoCpy;
status = connect ( piiu->sock, &piiu->dest.sa,
sizeof (piiu->dest.sa) );
if (status == 0) {
status = ::connect ( this->sock, &this->dest.sa,
sizeof ( this->dest.sa ) );
if ( status == 0 ) {
break;
}
errnoCpy = SOCKERRNO;
if (errnoCpy==SOCK_EISCONN) {
if ( errnoCpy == SOCK_EISCONN ) {
/*
* called connect after we are already connected
* (this appears to be how they provide
@@ -111,16 +111,7 @@ LOCAL void cac_connect_tcp (tcpiiu *piiu)
*/
break;
}
else if ( errnoCpy==SOCK_EINPROGRESS ||
errnoCpy==SOCK_EWOULDBLOCK /* for WINSOCK */ ) {
/*
* The socket is non-blocking and a
* connection attempt has been initiated,
* but not completed.
*/
return;
}
else if (errnoCpy==SOCK_EALREADY) {
else if ( errnoCpy == SOCK_EALREADY ) {
return;
}
#ifdef _WIN32
@@ -133,15 +124,20 @@ LOCAL void cac_connect_tcp (tcpiiu *piiu)
}
#endif
else if ( errnoCpy == SOCK_EINTR ) {
/*
* restart the system call if interrupted
*/
continue;
if ( this->state == iiu_disconnected ) {
return;
}
else {
continue;
}
}
else if ( errnoCpy == SOCK_SHUTDOWN ) {
return;
}
else {
ca_printf ("Unable to connect because %d=\"%s\"\n",
ca_printf ( "Unable to connect because %d=\"%s\"\n",
errnoCpy, SOCKERRSTR (errnoCpy) );
piiu->shutdown ();
this->shutdown ();
return;
}
}
@@ -149,9 +145,9 @@ LOCAL void cac_connect_tcp (tcpiiu *piiu)
/*
* put the iiu into the connected state
*/
piiu->state = iiu_connected;
this->state = iiu_connected;
piiu->rescheduleRecvTimer (); // reset connection activity watchdog
this->rescheduleRecvTimer (); // reset connection activity watchdog
return;
}
@@ -202,7 +198,7 @@ extern "C" void cacSendThreadTCP (void *pParam)
int status;
pOutBuf = static_cast <char *> ( cacRingBufferReadReserveNoBlock (&piiu->send, &sendCnt) );
while (!pOutBuf) {
while ( ! pOutBuf ) {
piiu->tcpSendWatchdog::cancel ();
pOutBuf = (char *) cacRingBufferReadReserve (&piiu->send, &sendCnt);
if ( piiu->state != iiu_connected ) {
@@ -229,25 +225,30 @@ extern "C" void cacSendThreadTCP (void *pParam)
cacRingBufferReadCommit (&piiu->send, 0);
if ( status == 0 ) {
semBinaryGive (piiu->sendThreadExitSignal);
piiu->shutdown ();
return;
break;
}
if ( localError == SOCK_SHUTDOWN ) {
break;
}
if ( localError != SOCK_EWOULDBLOCK && localError != SOCK_EINTR ) {
if ( localError != SOCK_EPIPE && localError != SOCK_ECONNRESET &&
localError != SOCK_ETIMEDOUT) {
ca_printf ("CAC: unexpected TCP send error: %s\n", SOCKERRSTR (localError) );
if ( localError == SOCK_EINTR ) {
if ( piiu->state == iiu_disconnected ) {
break;
}
else {
continue;
}
semBinaryGive ( piiu->sendThreadExitSignal );
piiu->shutdown ();
return;
}
if ( localError != SOCK_EPIPE && localError != SOCK_ECONNRESET &&
localError != SOCK_ETIMEDOUT) {
ca_printf ("CAC: unexpected TCP send error: %s\n", SOCKERRSTR (localError) );
}
piiu->shutdown ();
break;
}
}
@@ -286,7 +287,7 @@ void tcpiiu::recvMsg ()
return;
}
if ( localErrno == SOCK_EWOULDBLOCK || localErrno == SOCK_EINTR ) {
if ( localErrno == SOCK_EINTR ) {
return;
}
@@ -314,7 +315,7 @@ extern "C" void cacRecvThreadTCP (void *pParam)
{
tcpiiu *piiu = (tcpiiu *) pParam;
cac_connect_tcp (piiu);
piiu->connect ();
if ( piiu->state == iiu_connected ) {
unsigned priorityOfSelf = threadGetPrioritySelf ();
unsigned priorityOfSend;

View File

@@ -27,23 +27,28 @@ LOCAL int cac_udp_recv_msg (udpiiu *piiu)
int src_size = sizeof (src);
int status;
status = recvfrom (piiu->sock, piiu->recvBuf, sizeof (piiu->recvBuf), 0,
&src.sa, &src_size);
status = recvfrom ( piiu->sock, piiu->recvBuf, sizeof (piiu->recvBuf), 0,
&src.sa, &src_size );
if (status < 0) {
int errnoCpy = SOCKERRNO;
if (errnoCpy == SOCK_SHUTDOWN) {
if ( errnoCpy == SOCK_SHUTDOWN ) {
return -1;
}
if (errnoCpy == SOCK_EWOULDBLOCK || errnoCpy == SOCK_EINTR) {
return 0;
if ( errnoCpy == SOCK_EINTR ) {
if ( piiu->shutdownCmd ) {
return -1;
}
else {
return 0;
}
}
# ifdef linux
/*
* Avoid spurious ECONNREFUSED bug
* in linux
*/
if (errnoCpy==SOCK_ECONNREFUSED) {
if ( errnoCpy == SOCK_ECONNREFUSED ) {
return 0;
}
# endif
@@ -181,18 +186,16 @@ void notify_ca_repeater (udpiiu *piiu)
len = 0;
# endif
status = sendto (piiu->sock, (char *)&msg, len,
0, (struct sockaddr *)&saddr, sizeof(saddr));
if (status < 0) {
status = sendto ( piiu->sock, (char *) &msg, len,
0, (struct sockaddr *)&saddr, sizeof (saddr) );
if ( status < 0 ) {
int errnoCpy = SOCKERRNO;
if( errnoCpy != SOCK_EINTR &&
errnoCpy != SOCK_EWOULDBLOCK &&
if ( errnoCpy != SOCK_EINTR &&
/*
* This is returned from Linux when
* the repeater isnt running
*/
errnoCpy != SOCK_ECONNREFUSED
) {
errnoCpy != SOCK_ECONNREFUSED ) {
ca_printf (
"CAC: error sending to repeater was \"%s\"\n",
SOCKERRSTR(errnoCpy));
@@ -209,7 +212,7 @@ extern "C" void cacSendThreadUDP (void *pParam)
{
udpiiu *piiu = (udpiiu *) pParam;
while ( ! piiu->sendThreadExitCmd ) {
while ( ! piiu->shutdownCmd ) {
int status;
if (piiu->contactRepeater) {
@@ -222,13 +225,13 @@ extern "C" void cacSendThreadUDP (void *pParam)
osiSockAddrNode *pNode;
pNode = (osiSockAddrNode *) ellFirst (&piiu->dest);
while (pNode) {
while ( pNode ) {
assert ( piiu->nBytesInXmitBuf <= INT_MAX );
status = sendto (piiu->sock, piiu->xmitBuf,
status = sendto ( piiu->sock, piiu->xmitBuf,
(int) piiu->nBytesInXmitBuf, 0,
&pNode->addr.sa, sizeof(pNode->addr.sa));
if (status <= 0) {
&pNode->addr.sa, sizeof (pNode->addr.sa) );
if ( status <= 0 ) {
int localErrno = SOCKERRNO;
if (status==0) {
@@ -239,7 +242,12 @@ extern "C" void cacSendThreadUDP (void *pParam)
break;
}
else if ( localErrno == SOCK_EINTR ) {
status = 1;
if ( piiu->shutdownCmd ) {
break;
}
else {
continue;
}
}
else {
char buf[64];
@@ -258,17 +266,17 @@ extern "C" void cacSendThreadUDP (void *pParam)
piiu->nBytesInXmitBuf = 0u;
if (status<=0) {
if ( status <= 0 ) {
break;
}
}
semMutexGive (piiu->xmitBufLock);
semMutexGive ( piiu->xmitBufLock );
semBinaryMustTake (piiu->xmitSignal);
semBinaryMustTake ( piiu->xmitSignal );
}
semBinaryGive (piiu->sendThreadExitSignal);
semBinaryGive ( piiu->sendThreadExitSignal) ;
}
/*
@@ -342,7 +350,7 @@ udpiiu::udpiiu (cac *pcac) :
netiiu (pcac),
searchTmr (*this, pcac->timerQueue),
repeaterSubscribeTmr (*this, pcac->timerQueue),
sendThreadExitCmd (false)
shutdownCmd (false)
{
static const unsigned short PORT_ANY = 0u;
osiSockAddr addr;
@@ -580,7 +588,7 @@ udpiiu::~udpiiu ()
void udpiiu::shutdown ()
{
::shutdown (this->sock, SD_BOTH);
this->sendThreadExitCmd = true;
this->shutdownCmd = true;
semBinaryGive (this->xmitSignal);
}