diff options
Diffstat (limited to '')
-rw-r--r-- | src/stable/server.cpp | 97 |
1 files changed, 67 insertions, 30 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 | } |