diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2023-08-01 11:38:26 -0700 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2023-08-01 11:38:26 -0700 |
| commit | 87d76df1720e29e4195cf4a8845c07450fb3b2f2 (patch) | |
| tree | 6a62b8e4326570ccdbe01bfb8c71f408f6c01e2d /src | |
| parent | dcf2e2182934291e7312993c78d3d3c5f72597d5 (diff) | |
| download | libbu++-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.
Diffstat (limited to '')
| -rw-r--r-- | src/stable/server.cpp | 97 | ||||
| -rw-r--r-- | src/stable/server.h | 2 | ||||
| -rw-r--r-- | src/stable/sockettcp.h | 7 |
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 ) | |||
| 247 | Bu::Client *Bu::Server::getClient( fd iId ) | 247 | Bu::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 ) | |||
| 565 | void Bu::Server::IoWorker::handleWrite( Client *pClient, Socket *pSocket ) | 575 | void 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 |
