(file) Return to HTTPAcceptor.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/HTTPAcceptor.cpp between version 1.33 and 1.58

version 1.33, 2003/08/17 14:41:54 version 1.58, 2005/02/06 21:13:14
Line 1 
Line 1 
 //%/////////////////////////////////////////////////////////////////////////////  //%2005////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,  // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // The Open Group, Tivoli Systems  // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation, The Open Group.
   // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; VERITAS Software Corporation; The Open Group.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 27 
Line 33 
 //         Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com) //         Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
 //         Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com) //         Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
 //         Dave Rosckes (rosckes@us.ibm.com) //         Dave Rosckes (rosckes@us.ibm.com)
   //         Denise Eckstein (denise.eckstein@hp.com)
   //         Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090
   //         Amit Arora, IBM (amita@in.ibm.com) for Bug#2541
   //         Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
   //         Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
Line 59 
Line 70 
 #include "Tracer.h" #include "Tracer.h"
 #include <Pegasus/Common/MessageLoader.h> //l10n #include <Pegasus/Common/MessageLoader.h> //l10n
  
   #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
   #include "OS400ConvertChar.h"
   #endif
   
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
   static int MAX_CONNECTION_QUEUE_LENGTH = -1;
   
   
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
 // HTTPAcceptorRep // HTTPAcceptorRep
Line 92 
Line 110 
  
     struct sockaddr* address;     struct sockaddr* address;
  
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)  #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_VMS)
    size_t address_size;    size_t address_size;
 #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) && !defined(SUNOS_5_6)) #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) && !defined(SUNOS_5_6))
    socklen_t address_size;    socklen_t address_size;
Line 115 
Line 133 
                            MessageQueue* outputMessageQueue,                            MessageQueue* outputMessageQueue,
                            Boolean localConnection,                            Boolean localConnection,
                            Uint32 portNumber,                            Uint32 portNumber,
                            SSLContext * sslcontext)                             SSLContext * sslcontext,
                              Boolean exportConnection)
    : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  // ATTN: Need unique names?    : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  // ATTN: Need unique names?
      _monitor(monitor),      _monitor(monitor),
      _outputMessageQueue(outputMessageQueue),      _outputMessageQueue(outputMessageQueue),
Line 123 
Line 142 
      _entry_index(-1),      _entry_index(-1),
      _localConnection(localConnection),      _localConnection(localConnection),
      _portNumber(portNumber),      _portNumber(portNumber),
      _sslcontext(sslcontext)       _sslcontext(sslcontext),
        _exportConnection(exportConnection)
 { {
    Socket::initializeInterface();    Socket::initializeInterface();
   
      /*
           Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH differently.  Some platforms interpret
           the value literally, while others multiply a fudge factor. When the server is under
           stress from multiple clients with multiple requests, toggling this number may prevent clients from
           being dropped.  Instead of hard coding the value, we allow an environment variable to be set which
           specifies a number greater than the maximum concurrent client connections possible.  If this environment
           var is not specified, then MAX_CONNECTION_QUEUE_LENGTH = 15.
      */
   
   //To engage runtime backlog queue length: uncomment the following block AND comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15
   
   /*
      if(MAX_CONNECTION_QUEUE_LENGTH == -1){
   #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
   #pragma convert(37)
           const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
           EtoA(env);
   #pragma convert(0)
   #else
           const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
   #endif
           if(!env){
                   MAX_CONNECTION_QUEUE_LENGTH = 15;
           }else{
                   char *end = NULL;
                   MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10);
                   if(*end)
                           MAX_CONNECTION_QUEUE_LENGTH = 15;
                   cout << " MAX_CONNECTION_QUEUE_LENGTH = " << MAX_CONNECTION_QUEUE_LENGTH << endl;
           }
      }
   */
      MAX_CONNECTION_QUEUE_LENGTH = 15;
   
 } }
  
 HTTPAcceptor::~HTTPAcceptor() HTTPAcceptor::~HTTPAcceptor()
Line 156 
Line 211 
          else          else
          {          {
             // ATTN! this can't happen!             // ATTN! this can't happen!
               Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE received.");
          }          }
  
          break;          break;
Line 166 
Line 223 
          CloseConnectionMessage* closeConnectionMessage          CloseConnectionMessage* closeConnectionMessage
             = (CloseConnectionMessage*)message;             = (CloseConnectionMessage*)message;
  
          _rep->_connection_mut.lock(pegasus_thread_self());           AutoMutex autoMut(_rep->_connection_mut);
  
          for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)          for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
          {          {
Line 181 
Line 238 
                break;                break;
             }             }
          }          }
          _rep->_connection_mut.unlock();  
            break;
       }       }
  
       default:       default:
       // ATTN: need unexpected message error!       // ATTN: need unexpected message error!
         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
              "HTTPAcceptor::handleEnqueue: Invalid MESSAGE received.");
       break;       break;
    };    };
  
Line 198 
Line 258 
    Message* message = dequeue();    Message* message = dequeue();
  
    if (!message)    if (!message)
      {
         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
              "HTTPAcceptor::handleEnqueue(): No message on queue.");
       return;       return;
      }
  
    handleEnqueue(message);    handleEnqueue(message);
  
Line 209 
Line 273 
    if (_rep){    if (_rep){
         //l10n         //l10n
       //throw BindFailedException("HTTPAcceptor already bound");       //throw BindFailedException("HTTPAcceptor already bound");
       String s0 = "HTTPAcceptor";  
       MessageLoaderParms parms("Common.HTTPAcceptor.ALREADY_BOUND",       MessageLoaderParms parms("Common.HTTPAcceptor.ALREADY_BOUND",
                                                    "$0 already bound",                                 "HTTPAcceptor already bound");
                                                    s0);  
         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
              "HTTPAcceptor::bind: HTTPAcceptor already bound.");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
Line 243 
Line 309 
            AF_UNIX;            AF_UNIX;
        strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,        strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,
               PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);               PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
   #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
          AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
   #endif
        ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);        ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 #else #else
        PEGASUS_ASSERT(false);        PEGASUS_ASSERT(false);
Line 277 
Line 346 
       //throw BindFailedException("Failed to create socket");       //throw BindFailedException("Failed to create socket");
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_CREATE_SOCKET",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_CREATE_SOCKET",
                                                    "Failed to create socket");                                                    "Failed to create socket");
         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
              "HTTPAcceptor::_bind _rep->socket < 0");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
  
 // set the close-on-exec bit for this file handle. // set the close-on-exec bit for this file handle.
 // any unix that forks needs this bit set. // any unix that forks needs this bit set.
 #ifndef PEGASUS_PLATFORM_WIN32_IX86_MSVC  #if !defined PEGASUS_PLATFORM_WIN32_IX86_MSVC && !defined(PEGASUS_OS_VMS)
    int sock_flags;    int sock_flags;
  if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0)  if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0)
    {    {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_GETFD) failed");                    "HTTPAcceptor::_bind: fcntl(F_GETFD) failed");
    }    }
    else    else
    {    {
       sock_flags |= FD_CLOEXEC;       sock_flags |= FD_CLOEXEC;
       if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0)       if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0)
       {       {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_SETFD) failed");                    "HTTPAcceptor::_bind: fcntl(F_SETFD) failed");
       }       }
    }    }
 #endif #endif
Line 319 
Line 390 
       //throw BindFailedException("Failed to set socket option");       //throw BindFailedException("Failed to set socket option");
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SET_SOCKET_OPTION",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SET_SOCKET_OPTION",
                                                    "Failed to set socket option");                                                    "Failed to set socket option");
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                      "HTTPAcceptor::_bind: Failed to set socket option.");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
Line 333 
Line 406 
       //throw BindFailedException("Failed to bind socket");       //throw BindFailedException("Failed to bind socket");
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
                                                    "Failed to bind socket");                                                    "Failed to bind socket");
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                           "HTTPAcceptor::_bind: Failed to bind socket.");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
      //
      //  Change permissions on Linux local domain socket to allow writes by others.
      //
   #if defined(PEGASUS_LOCAL_DOMAIN_SOCKET) && defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
      if (_localConnection)
      {
        if (::chmod( PEGASUS_LOCAL_DOMAIN_SOCKET_PATH,
                     S_IRUSR | S_IWUSR | S_IXUSR |
                     S_IRGRP | S_IWGRP | S_IXGRP |
                     S_IROTH | S_IWOTH | S_IXOTH ) < 0 )
        {
          Socket::close(_rep->socket);
          delete _rep;
          _rep = 0;
          //l10n
          //throw BindFailedException("Failed to bind socket");
          MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
                                  "Failed to bind socket");
          PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "HTTPAcceptor::_bind: Failed to set domain socket permissions.");
          throw BindFailedException(parms);
        }
      }
   #endif
   
    // Set up listening on the given socket:    // Set up listening on the given socket:
  
    int const MAX_CONNECTION_QUEUE_LENGTH = 5;     //int const MAX_CONNECTION_QUEUE_LENGTH = 15;
  
    if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0)    if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0)
    {    {
Line 349 
Line 449 
       //throw BindFailedException("Failed to bind socket");       //throw BindFailedException("Failed to bind socket");
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
                                                    "Failed to bind socket");                                                    "Failed to bind socket");
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                     "HTTPAcceptor::_bind: Failed to bind socket(1).");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
Line 367 
Line 469 
       //throw BindFailedException("Failed to solicit socket messaeges");       //throw BindFailedException("Failed to solicit socket messaeges");
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",
                                                    "Failed to solicit socket messaeges");                                                    "Failed to solicit socket messaeges");
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                     "HTTPAcceptor::_bind: Failed to solicit socket messages(2).");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
 } }
Line 380 
Line 484 
    if (_rep)    if (_rep)
    {    {
       // unregister the socket       // unregister the socket
       _monitor->unsolicitSocketMessages(_rep->socket);  
         // ATTN - comment out - see CIMServer::stopClientConnection()
         //_monitor->unsolicitSocketMessages(_rep->socket);
  
       // close the socket       // close the socket
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
    }    }
      else
      {
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                           "HTTPAcceptor::closeConnectionSocket failure _rep is null." );
      }
 } }
  
 /** /**
Line 396 
Line 507 
    {    {
       _bind();       _bind();
    }    }
      else
      {
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                           "HTTPAcceptor::reopenConnectionSocket failure _rep is null." );
      }
 } }
  
 /** /**
Line 405 
Line 521 
 { {
    Uint32 count = 0;    Uint32 count = 0;
  
    _rep->_connection_mut.lock(pegasus_thread_self());     AutoMutex autoMut(_rep->_connection_mut);
    if (_rep->connections.size() > 0)    if (_rep->connections.size() > 0)
    {    {
       HTTPConnection* connection = _rep->connections[0];       HTTPConnection* connection = _rep->connections[0];
       count = connection->getRequestCount();       count = connection->getRequestCount();
    }    }
    _rep->_connection_mut.unlock();  
    return count;    return count;
 } }
  
Line 434 
Line 550 
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
    }    }
      else
      {
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "HTTPAcceptor::unbind failure _rep is null." );
      }
 } }
  
 void HTTPAcceptor::destroyConnections() void HTTPAcceptor::destroyConnections()
Line 442 
Line 563 
  
    // For each connection created by this object:    // For each connection created by this object:
  
    _rep->_connection_mut.lock(pegasus_thread_self());     AutoMutex autoMut(_rep->_connection_mut);
    for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)    for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
    {    {
       HTTPConnection* connection = _rep->connections[i];       HTTPConnection* connection = _rep->connections[i];
Line 459 
Line 580 
    }    }
  
    _rep->connections.clear();    _rep->connections.clear();
    _rep->_connection_mut.unlock();  
 } }
  
 void HTTPAcceptor::_acceptConnection() void HTTPAcceptor::_acceptConnection()
Line 474 
Line 595 
    // Accept the connection (populate the address):    // Accept the connection (populate the address):
  
    struct sockaddr* accept_address;    struct sockaddr* accept_address;
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)  #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_VMS)
    size_t address_size;    size_t address_size;
 #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) && !defined(SUNOS_5_6))  #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_OS_SOLARIS) && !defined(SUNOS_5_6))
    socklen_t address_size;    socklen_t address_size;
 #else #else
    int address_size;    int address_size;
Line 503 
Line 624 
  
    if (socket < 0)    if (socket < 0)
    {    {
   
        Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,        Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
                    "HTTPAcceptor - accept() failure.  errno: $0"                    "HTTPAcceptor - accept() failure.  errno: $0"
                    ,errno);                    ,errno);
  
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: accept() failed");                         "HTTPAcceptor: accept() failed");
       return;       return;
    }    }
  
 // set the close on exec flag // set the close on exec flag
 #ifndef PEGASUS_PLATFORM_WIN32_IX86_MSVC  #if !defined PEGASUS_PLATFORM_WIN32_IX86_MSVC && !defined(PEGASUS_OS_VMS)
    int sock_flags;    int sock_flags;
  if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0)  if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0)
    {    {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_GETFD) failed");                         "HTTPAcceptor: fcntl(F_GETFD) failed");
    }    }
    else    else
Line 525 
Line 647 
       sock_flags |= FD_CLOEXEC;       sock_flags |= FD_CLOEXEC;
       if (fcntl(socket, F_SETFD, sock_flags) < 0)       if (fcntl(socket, F_SETFD, sock_flags) < 0)
       {       {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_SETFD) failed");                         "HTTPAcceptor: fcntl(F_SETFD) failed");
       }       }
    }    }
Line 538 
Line 660 
  
    // Create a new conection and add it to the connection list:    // Create a new conection and add it to the connection list:
  
    MP_Socket * mp_socket = new MP_Socket(socket, _sslcontext);     AutoPtr<MP_Socket> mp_socket(new MP_Socket(socket, _sslcontext, _exportConnection));
    if (mp_socket->accept() < 0)    if (mp_socket->accept() < 0)
    {    {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: SSL_accept() failed");                         "HTTPAcceptor: SSL_accept() failed");
          mp_socket->close();
       return;       return;
    }    }
  
    HTTPConnection* connection = new HTTPConnection(     HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,
       _monitor, mp_socket, this, static_cast<MessageQueue *>(_outputMessageQueue));         this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection);
  
    // Solicit events on this new connection's socket:    // Solicit events on this new connection's socket:
    int index;    int index;
  
    if (-1 ==  (index = _monitor->solicitSocketMessages(    if (-1 ==  (index = _monitor->solicitSocketMessages(
           socket,            connection->getSocket(),
           SocketMessage::READ | SocketMessage::EXCEPTION,           SocketMessage::READ | SocketMessage::EXCEPTION,
           connection->getQueueId(), Monitor::CONNECTION)) )           connection->getQueueId(), Monitor::CONNECTION)) )
    {    {
         // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return
         // an error message to Client application.
         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
             "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in _entries table failed.");
       delete connection;       delete connection;
       Socket::close(socket);       Socket::close(socket);
         return;
    }    }
  
    // Save the socket for cleanup later:    // Save the socket for cleanup later:
    connection->_entry_index = index;    connection->_entry_index = index;
       _rep->_connection_mut.lock(pegasus_thread_self());     AutoMutex autoMut(_rep->_connection_mut);
    _rep->connections.append(connection);    _rep->connections.append(connection);
    _rep->_connection_mut.unlock();  
 }  
   
 AsyncDQueue<pegasus_acceptor> pegasus_acceptor::acceptors(true, 0);  
   
 pegasus_acceptor::pegasus_acceptor(monitor_2* monitor,  
                                    MessageQueue* outputMessageQueue,  
                                    Boolean localConnection,  
                                    Uint32 portNumber,  
                                    SSLContext* sslcontext)  
   : _monitor(monitor), _outputMessageQueue(outputMessageQueue),  
     _localConnection(localConnection), _portNumber(portNumber),  
     _sslcontext(sslcontext), connections(true, 0)  
 {  
   
      Socket::initializeInterface();  
      try {  
        acceptors.insert_first(this);  
      }  
      catch(...){  
      }  
   
 }  
   
 pegasus_acceptor::~pegasus_acceptor(void)  
 {  
    unbind();  
    Socket::uninitializeInterface();  
    try {  
      acceptors.remove(this);  
    }  
    catch(...){  
    }  
  
 } }
  
   
 void pegasus_acceptor::bind()  
 {  
   
   PEGASUS_SOCKLEN_SIZE addr_size;  
   struct sockaddr *addr;  
   struct sockaddr_in addr_in;  
 # ifdef PEGASUS_LOCAL_DOMAIN_SOCKET  
   struct sockaddr_un addr_un;  
 #endif  
   
   memset(&addr_in, 0, sizeof(addr_in));  
   addr_in.sin_addr.s_addr = INADDR_ANY;  
   addr_in.sin_family = AF_INET;  
   addr_in.sin_port = htons(_portNumber);  
   addr = (struct sockaddr*) &addr_in;  
   addr_size = sizeof(addr_in);  
   
   // first step: determine which kind of socket factory to initialize,  
   // then create the socket and bind it to an address  
   if(_localConnection == true){  
 #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET  
     unix_socket_factory sf;  
     pegasus_socket temp(&sf);  
     _listener = temp;  
   
     memset(&addr_un, 0, sizeof(addr_un));  
     addr_un.sun_family = AF_UNIX;  
     strcpy(addr_un.sun_path, PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);  
     addr = (struct sockaddr*) &addr_un;  
     addr_size = sizeof(addr_un);  
     _listener.socket(AF_UNIX, SOCK_STREAM, 0);  
 #else  
     bsd_socket_factory sf;  
     pegasus_socket temp(&sf);  
     _listener = temp;  
     _listener.socket(AF_UNIX, SOCK_STREAM, 0);  
 #endif  
   }  
   else if( _sslcontext != 0 ) {  
 #ifdef PEGASUS_HAS_SSL  
     ssl_socket_factory sf;  
 #else  
     bsd_socket_factory sf;  
 #endif  
     pegasus_socket temp(&sf);  
     _listener = temp;  
     _listener.socket(PF_INET, SOCK_STREAM, 0);  
   }  
   else {  
     bsd_socket_factory sf;  
     pegasus_socket temp(&sf);  
     _listener = temp;  
     _listener.socket(PF_INET, SOCK_STREAM, 0);  
   }  
   
   _listener.bind((struct sockaddr*)addr, addr_size);  
   
   // second step: listen on the socket  
   
   _listener.listen(5);  
   
   // third step: add this listening socket to the monitor  
   
    _monitor->tickle();  
    _monitor->add_entry(_listener, LISTEN, this, this);  
 }  
   
   
 /** Unbind from the given port.  
  */  
 void pegasus_acceptor::unbind()  
 {  
   // remove the socket from the monitor  
   _monitor->remove_entry((Sint32)_listener);  
   
   // close the socket  
   _listener.close();  
 }  
   
   
       /** Close the connection socket.  
        */  
 void pegasus_acceptor::closeConnectionSocket()  
 {  
   unbind();  
 }  
   
   
       /** Reopen the connection socket.  
        */  
 void pegasus_acceptor::reopenConnectionSocket()  
 {  
   bind();  
 }  
   
   
   /** Returns the number of outstanding requests  
    */  
 Uint32 pegasus_acceptor::getOutstandingRequestCount()  
 {  
   return _monitor->getOutstandingRequestCount();  
 }  
   
 Boolean pegasus_acceptor::operator ==(const pegasus_acceptor& pa)  
 {  
   if(this == &pa)  
     return true;  
   return false;  
 }  
   
 Boolean pegasus_acceptor::operator ==(void* pa)  
 {  
   if((void*)this == pa)  
     return true;  
   return false;  
 }  
   
   
 pegasus_acceptor* pegasus_acceptor::find_acceptor(Boolean local, Uint32 port)  
 {  
   pegasus_acceptor* temp = 0;  
   
   try {  
     acceptors.try_lock(pegasus_thread_self());  
     temp = acceptors.next(temp);  
     while(temp){  
       if( local == true ){  
         if(temp->_localConnection){  
           acceptors.unlock();  
           return temp;  
         }  
       }  
       if(temp->_localConnection == local && temp->_portNumber ==port){  
         acceptors.unlock();  
         return temp;  
       }  
       temp = acceptors.next(temp);  
     }  
     acceptors.unlock();  
   }  
   catch(...){  
   }  
   return temp;  
 }  
   
 class m2e_rep;  
   
 void pegasus_acceptor::accept_dispatch(monitor_2_entry *entry)  
 {  
   pegasus_acceptor* myself = (pegasus_acceptor*)entry->get_accept();  
   
   HTTPConnection2* connection = new HTTPConnection2(entry->_rep->psock, myself->_outputMessageQueue);  
   
   // set the entry's dispatch parameter to point to the connection object  
   entry->set_dispatch ((void*)connection);  
   
   try {  
     myself->connections.insert_first(connection);  
   }  
   catch(...){  
   }  
 }  
   
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.33  
changed lines
  Added in v.1.58

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2