aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2023-08-01 11:38:26 -0700
committerMike Buland <eichlan@xagasoft.com>2023-08-01 11:38:26 -0700
commit87d76df1720e29e4195cf4a8845c07450fb3b2f2 (patch)
tree6a62b8e4326570ccdbe01bfb8c71f408f6c01e2d
parentdcf2e2182934291e7312993c78d3d3c5f72597d5 (diff)
downloadlibbu++-87d76df1720e29e4195cf4a8845c07450fb3b2f2.tar.gz
libbu++-87d76df1720e29e4195cf4a8845c07450fb3b2f2.tar.bz2
libbu++-87d76df1720e29e4195cf4a8845c07450fb3b2f2.tar.xz
libbu++-87d76df1720e29e4195cf4a8845c07450fb3b2f2.zip
Fixed issues around disconnected sockets.
We were bailing out when sockets closed, that was silly.
-rw-r--r--src/stable/server.cpp97
-rw-r--r--src/stable/server.h2
-rw-r--r--src/stable/sockettcp.h7
3 files changed, 75 insertions, 31 deletions
diff --git a/src/stable/server.cpp b/src/stable/server.cpp
index 3aa8a34..6ee7d6e 100644
--- a/src/stable/server.cpp
+++ b/src/stable/server.cpp
@@ -247,6 +247,8 @@ void Bu::Server::addClient( const Bu::ServerSocket *pSrv, Bu::Socket *pSocket )
247Bu::Client *Bu::Server::getClient( fd iId ) 247Bu::Client *Bu::Server::getClient( fd iId )
248{ 248{
249 Bu::MutexLocker l( mClients ); 249 Bu::MutexLocker l( mClients );
250 if( !hClients.has( iId ) )
251 return NULL;
250 return hClients.get( iId ); 252 return hClients.get( iId );
251} 253}
252 254
@@ -520,30 +522,38 @@ void Bu::Server::IoWorker::handleRead( Client *pClient, Socket *pSocket )
520 Bu::size iTotal=0; 522 Bu::size iTotal=0;
521 523
522 BU_PROFILE_START("client.read"); 524 BU_PROFILE_START("client.read");
523 for(;;) 525 try
524 { 526 {
525 try 527 for(;;)
526 { 528 {
527 iRead = pSocket->read( buf, RBS ); 529 try
528
529 if( iRead == 0 )
530 { 530 {
531 break; 531 iRead = pSocket->read( buf, RBS );
532
533 if( iRead == 0 )
534 {
535 break;
536 }
537 else
538 {
539 iTotal += iRead;
540 pClient->cbBuffer.server().write( buf, iRead );
541 if( !pSocket->canRead() )
542 break;
543 }
532 } 544 }
533 else 545 catch( Bu::ExceptionBase &e )
534 { 546 {
535 iTotal += iRead; 547 pClient->disconnect();
536 pClient->cbBuffer.server().write( buf, iRead ); 548 //close( pSocket );
537 if( !pSocket->canRead() ) 549 return;
538 break;
539 } 550 }
540 } 551 }
541 catch( Bu::ExceptionBase &e ) 552 }
542 { 553 catch( std::exception &e )
543 pClient->disconnect(); 554 {
544 //close( pSocket ); 555 // Probably the socket is dead. We should maybe disconnect, but we'll
545 return; 556 // also notice soon enough anyway?
546 }
547 } 557 }
548 BU_PROFILE_END("client.read"); 558 BU_PROFILE_END("client.read");
549 559
@@ -565,12 +575,28 @@ void Bu::Server::IoWorker::handleRead( Client *pClient, Socket *pSocket )
565void Bu::Server::IoWorker::handleWrite( Client *pClient, Socket *pSocket ) 575void Bu::Server::IoWorker::handleWrite( Client *pClient, Socket *pSocket )
566{ 576{
567 char buf[RBS]; 577 char buf[RBS];
568 while( pClient->hasOutput() > 0 ) 578 try
579 {
580 while( pClient->hasOutput() )
581 {
582 int iAmnt = RBS;
583 iAmnt = pClient->cbBuffer.server().peek( buf, iAmnt );
584 int iReal = pSocket->write( buf, iAmnt );
585 pClient->cbBuffer.server().seek( iReal );
586 if( iReal < iAmnt )
587 {
588 // We wrote less than expected, the kernel buffer must be full,
589 // we should queue ourselves again.
590 rSrv.clientWriteReady( pClient->getId() );
591 break;
592 }
593 }
594 }
595 catch( std::exception &e )
569 { 596 {
570 int iAmnt = RBS; 597 // Error working with socket, it's probably closed.
571 iAmnt = pClient->cbBuffer.server().peek( buf, iAmnt ); 598 if( pClient->hasOutput() )
572 int iReal = pSocket->write( buf, iAmnt ); 599 rSrv.clientWriteReady( pClient->getId() );
573 pClient->cbBuffer.server().seek( iReal );
574 } 600 }
575} 601}
576 602
@@ -596,17 +622,28 @@ void Bu::Server::ClientWorker::run()
596 if( pEv == NULL ) 622 if( pEv == NULL )
597 continue; 623 continue;
598 624
599 Client *pClient = rSrv.getClient( pEv->getId() ); 625 try
600 if( pClient == NULL )
601 { 626 {
602 delete pEv; 627 Client *pClient = rSrv.getClient( pEv->getId() );
603 continue; 628 if( pClient == NULL )
629 {
630 delete pEv;
631 continue;
632 }
633
634 pClient->processInput();
635 if( pClient->getOutputSize() > 0 )
636 {
637 rSrv.clientWriteReady( pClient->getId() );
638 }
604 } 639 }
605 640 catch( std::exception &e )
606 pClient->processInput(); 641 {
607 if( pClient->getOutputSize() > 0 ) 642 // Probably we're fine, the client just closed between queuing and
643 // working.
644 }
645 catch(...)
608 { 646 {
609 rSrv.clientWriteReady( pClient->getId() );
610 } 647 }
611 delete pEv; 648 delete pEv;
612 } 649 }
diff --git a/src/stable/server.h b/src/stable/server.h
index 9fb8282..a9680cf 100644
--- a/src/stable/server.h
+++ b/src/stable/server.h
@@ -23,7 +23,7 @@
23#include "bu/config.h" 23#include "bu/config.h"
24 24
25#ifndef PROFILE_BU_SERVER 25#ifndef PROFILE_BU_SERVER
26 #define PROFILE_BU_SERVER 1 26// #define PROFILE_BU_SERVER 1
27#endif 27#endif
28 28
29#ifdef PROFILE_BU_SERVER 29#ifdef PROFILE_BU_SERVER
diff --git a/src/stable/sockettcp.h b/src/stable/sockettcp.h
index 3fc14ef..8539b52 100644
--- a/src/stable/sockettcp.h
+++ b/src/stable/sockettcp.h
@@ -48,7 +48,14 @@ namespace Bu
48 ... 48 ...
49 ... 49 ...
50 ... 50 ...
51 // sigset is deprecated
51 sigset( SIGPIPE, SIG_IGN ); // do this before you use a Bu::SocketTcp 52 sigset( SIGPIPE, SIG_IGN ); // do this before you use a Bu::SocketTcp
53
54 // this is the modern Linux alternative
55 struct sigaction saIgnore;
56 memset( &saIgnore, 0, sizeof(struct sigaction) );
57 saIgnore.sa_handler = SIG_IGN;
58 sigaction( SIGPIPE, &saIgnore, NULL );
52 @endcode 59 @endcode
53 * When this is done, Bu::SocketTcp will simply throw a broken pipe 60 * When this is done, Bu::SocketTcp will simply throw a broken pipe
54 * exception just like every other error condition, allowing your program 61 * exception just like every other error condition, allowing your program