APR Networking & the Reactor Pattern
by Ethan Q. McCallum 

Listing One

int main( const int argc , const char** argv ){
   const char* listenString = argv[1] ;
   // ... initialize APR 
   // ... setup memory pool "mainMemPool" ...
   apr_socket_t* serverSocket ;
   // create socket
   apr_socket_create(          /* 1 */
      &serverSocket , 
      APR_INET ,
      SOCK_STREAM ,
      APR_PROTO_TCP ,
      mainMemPool
   ) ;
   // set options
   apr_socket_opt_set(
      serverSocket ,
      APR_SO_REUSEADDR ,
      TRUE // "TRUE" --> APR constant
   ) ;
   // create sockaddr_t
   apr_sockaddr_t* sockAddr = NULL ;
   char* listenHost ;
   char* scopeID ; // unused
   apr_port_t listenPort ;
   apr_parse_addr_port(         /* 2 */
      &listenHost ,
      &scopeID ,
      &listenPort ,
      listenString ,
      mainMemPool
   ) ;
   apr_sockaddr_info_get(       /* 3 */
      &sockAddr ,
      listenHost ,
      APR_UNSPEC , // let system decide
      listenPort ,
      0 ,
      mainMemPool
   ) ;
   // bind
   aprResult = apr_socket_bind(     /* 4 */
      serverSocket ,
      sockAddr
   ) ;
   // listen
   aprResult = apr_socket_listen(   /* 5 */
      serverSocket ,
      15
   ) ;
   apr_socket_t* clientSocket = NULL ;
   while( true ){
      std::cout << "accepting ..." << std::endl ;
      aprResult = apr_socket_accept(    /* 6 */
         &clientSocket ,
         serverSocket ,
         mainMemPool
      ) ;
      try{
         handleClient( clientSocket , interpreter ) ;
      }catch( const std::runtime_error& swallowed ){
         // ... handle exception ...
      }
      apr_socket_shutdown( clientSocket , APR_SHUTDOWN_READWRITE ) ;
      apr_socket_close( clientSocket ) ;
      std::cout << "closed" << std::endl ;
      clientSocket = NULL ;
   }
   // cleanup
   aprResult = apr_socket_close( serverSocket ) ;
} // main()





2


