Vault  4.1
vlistenersocket.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved.
00003 This file is part of the Code Vault version 4.1
00004 http://www.bombaydigital.com/
00005 License: MIT. See LICENSE.md in the Vault top level directory.
00006 */
00007 
00010 #include "vlistenersocket.h"
00011 #include "vtypes_internal.h"
00012 
00013 #include "vexception.h"
00014 #include "vsocketfactory.h"
00015 
00016 VListenerSocket::VListenerSocket(int portNumber, const VString& bindAddress, VSocketFactory* factory, int backlog)
00017     : VSocket()
00018     , mBindAddress(bindAddress)
00019     , mBacklog(backlog)
00020     , mFactory(factory)
00021     {
00022     this->setHostIPAddressAndPort(VSTRING_FORMAT("listener(%s:%d)", bindAddress.chars(), portNumber), portNumber);
00023 
00024     /*
00025     We need to have our listen() calls timeout if we expect to allow
00026     other threads (e.g., a thread that is handling a remote server
00027     management command) to shut us down. Otherwise, we'll be blocked
00028     on listen() and never get a chance to even check isRunning().
00029     */
00030     struct timeval timeout;
00031 
00032     timeout.tv_sec = 5;
00033     timeout.tv_usec = 0;
00034 
00035     VListenerSocket::setReadTimeOut(timeout);
00036 }
00037 
00038 VListenerSocket::~VListenerSocket() {
00039 }
00040 
00041 VSocket* VListenerSocket::accept() {
00042     if (mSocketID == kNoSocketID) {
00043         throw VStackTraceException("VListenerSocket::accept called before socket is listening.");
00044     }
00045 
00046     struct sockaddr_in  clientaddr;
00047     VSocklenT           clientaddrLength = sizeof(clientaddr);
00048     VSocketID           handlerSockID = kNoSocketID;
00049     VSocket*            handlerSocket = NULL;
00050     bool                shouldAccept = true;
00051 
00052     if (mReadTimeOutActive) {
00053         /* then we need to do a select call */
00054         struct timeval  timeout = mReadTimeOut;
00055         fd_set          readset;
00056 
00057         FD_ZERO(&readset);
00058         //lint -e573 Signed-unsigned mix with divide"
00059         FD_SET(mSocketID, &readset);
00060 
00061         int result = ::select(static_cast<int>(mSocketID + 1), &readset, NULL, NULL, &timeout);
00062 
00063         if (result == -1) {
00064             throw VException(VSystemError::getSocketError(), VSTRING_FORMAT("VListenerSocket[%s:%d]::accept select() failed.", mBindAddress.chars(), mPortNumber));
00065         }
00066 
00067         //lint -e573 Signed-unsigned mix with divide"
00068         shouldAccept = ((result > 0) && FD_ISSET(mSocketID, &readset));
00069     }
00070 
00071     if (shouldAccept) {
00072         ::memset(&clientaddr, 0, static_cast<Vu32>(clientaddrLength));
00073         handlerSockID = ::accept(mSocketID, (struct sockaddr*) &clientaddr, &clientaddrLength);
00074 
00075         if (handlerSockID == kNoSocketID) {
00076             throw VException(VSystemError::getSocketError(), VSTRING_FORMAT("VListenerSocket[%s:%d]::accept accept() failed.", mBindAddress.chars(), mPortNumber));
00077         } else {
00078             handlerSocket = mFactory->createSocket(handlerSockID);
00079         }
00080     }
00081 
00082     return handlerSocket;
00083 }
00084 
00085 void VListenerSocket::listen() {
00086     this->_listen(mBindAddress, mBacklog);
00087 }
00088 

Copyright ©1997-2014 Trygve Isaacson. All rights reserved. This documentation was generated with Doxygen.