Пример #1
0
int
MultiProcessDatagramServer::run()
{
    if (!ok_) return(-1);

    char buf[BUFSIZ+1];
    size_t count;

    UseCntPtr<Address> peer_address(serverep_.getInternalAddress().create());

    (void) signal(SIGCHLD, reaper);

    while ( true )
    {
        count = BUFSIZ;
        count = serverep_.read(buf, count, *peer_address);
        if (count > 0)
        {
            int pid = fork();
            if (pid == 0)
            {
                // child
                int status = handler_(serverep_, *peer_address, buf, count);
                serverep_.close();
                exit(status);
            }
            else if (pid < 0)
            {
                // error in parent
                return(-1);
            }
        }
        else if (count == 0)
        {
            // end-of-file -- done.
            break;
        }
        else
        {
            // error. ignore interrupts
            if (errno == EINTR)
                continue;
            else
                return(-1);
        }
    }

    return(0);
}
Пример #2
0
void
do_work (RPG_Net_Protocol_Configuration& configuration_in,
         const std::string& serverHostname_in,
         unsigned short serverPortNumber_in,
         unsigned int numDispatchThreads_in)
{
  RPG_TRACE (ACE_TEXT ("::do_work"));

  // step1: initialize event dispatch
  if (!Common_Tools::initializeEventDispatch (RPG_NET_USES_REACTOR,
                                              numDispatchThreads_in,
                                              configuration_in.streamConfiguration.serializeOutput))
  {
    ACE_DEBUG ((LM_ERROR,
                ACE_TEXT ("failed to init event dispatch, returning\n")));
    return;
  } // end IF

  // step2: initialize client connector
  Net_SocketHandlerConfiguration_t socket_handler_configuration;
  socket_handler_configuration.bufferSize = RPG_NET_PROTOCOL_BUFFER_SIZE;
  socket_handler_configuration.messageAllocator =
    configuration_in.streamConfiguration.messageAllocator;
  socket_handler_configuration.socketConfiguration =
    configuration_in.socketConfiguration;
  Net_Client_IConnector_t* connector_p = NULL;
  if (RPG_NET_USES_REACTOR)
    ACE_NEW_NORETURN (connector_p,
                      RPG_Net_Protocol_Connector_t (&socket_handler_configuration,
                                                    RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance (),
                                                    0));
  else
    ACE_NEW_NORETURN (connector_p,
                      RPG_Net_Protocol_AsynchConnector_t (&socket_handler_configuration,
                                                          RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance (),
                                                          0));
  if (!connector_p)
  {
    ACE_DEBUG ((LM_CRITICAL,
                ACE_TEXT ("failed to allocate memory, aborting\n")));
    return;
  } // end IF

  // step3: initialize signal handling
  IRC_Client_SignalHandler signal_handler (serverHostname_in,   // target hostname
                                           serverPortNumber_in, // target port
                                           connector_p);        // connector
  ACE_Sig_Handlers signal_handlers;
  // *WARNING*: 'signals' appears to be a reserved keyword in some contexts...
  ACE_Sig_Set signal_set (0);
  do_initializeSignals (true,  // allow SIGUSR1
                        signal_set);
  Common_SignalActions_t previous_signal_actions;
  ACE_Sig_Set ignored_signal_set (0);
  if (!Common_Tools::initializeSignals (signal_set,
                                        ignored_signal_set,
                                        &signal_handler,
                                        previous_signal_actions))
  {
    ACE_DEBUG ((LM_ERROR,
                ACE_TEXT ("failed to initialize signal handling, returning\n")));

    // clean up
    delete connector_p;

    return;
  } // end IF

  // step4a: initialize connection manager
  RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance ()->initialize (std::numeric_limits<unsigned int>::max ());
  RPG_Net_Protocol_SessionData session_data;
  RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance ()->set (configuration_in,
                                                                  &session_data);

  //// step5a: start GTK event loop
  //COMMON_UI_GTK_MANAGER_SINGLETON::instance ()->start ();
  //if (!COMMON_UI_GTK_MANAGER_SINGLETON::instance ()->isRunning ())
  //{
  //  ACE_DEBUG ((LM_ERROR,
  //              ACE_TEXT ("failed to start GTK event dispatch, aborting\n")));

  //  // clean up
  //  delete connector_p;
  //  Common_Tools::finalizeSignals (signal_set,
  //                                 RPG_NET_USES_REACTOR,
  //                                 previous_signal_actions);

  //  return;
  //} // end IF

  // step5b: initialize worker(s)
  int group_id = -1;
  if (!Common_Tools::startEventDispatch (RPG_NET_USES_REACTOR,
                                         numDispatchThreads_in,
                                         group_id))
  {
    ACE_DEBUG ((LM_ERROR,
                ACE_TEXT ("failed to start event dispatch, aborting\n")));

    // clean up
    COMMON_UI_GTK_MANAGER_SINGLETON::instance ()->stop ();
    delete connector_p;
    Common_Tools::finalizeSignals (signal_set,
                                   RPG_NET_USES_REACTOR,
                                   previous_signal_actions);

    return;
  } // end IF

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("started event dispatch...\n")));

  // step6: (try to) connect to the server
  ACE_INET_Addr peer_address (serverPortNumber_in,
                              serverHostname_in.c_str ());
  bool result = connector_p->connect (peer_address);
  if (!RPG_NET_USES_REACTOR)
  {
    ACE_Time_Value delay (1, 0);
    ACE_OS::sleep (delay);
    if (RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance ()->numConnections () != 1)
      result = false;
  } // end IF
  if (!result)
  {
    // debug info
    ACE_TCHAR buffer[BUFSIZ];
    ACE_OS::memset (buffer, 0, sizeof (buffer));
    int result = peer_address.addr_to_string (buffer,
                                              sizeof (buffer));
    if (result == -1)
      ACE_DEBUG ((LM_ERROR,
                  ACE_TEXT ("failed to ACE_INET_Addr::addr_to_string(): \"%m\", continuing\n")));
    ACE_DEBUG ((LM_ERROR,
                ACE_TEXT ("failed to connect(\"%s\"): \"%m\", returning\n"),
                buffer));

    // clean up
    COMMON_UI_GTK_MANAGER_SINGLETON::instance ()->stop ();
    delete connector_p;
    Common_Tools::finalizeSignals (signal_set,
                                   RPG_NET_USES_REACTOR,
                                   previous_signal_actions);

    return;
  } // end IF

  // *NOTE*: from this point on, we need to clean up any remote connections !

  // step7: dispatch events
  // *NOTE*: when using a thread pool, handle things differently...
  if (numDispatchThreads_in > 1)
  {
    if (ACE_Thread_Manager::instance ()->wait_grp (group_id) == -1)
      ACE_DEBUG ((LM_ERROR,
                  ACE_TEXT ("failed to ACE_Thread_Manager::wait_grp(%d): \"%m\", continuing\n"),
                  group_id));
  } // end IF
  else
  {
    if (RPG_NET_USES_REACTOR)
    {
      /*      // *WARNING*: restart system calls (after e.g. SIGINT) for the reactor
      ACE_Reactor::instance()->restart(1);
      */
      if (ACE_Reactor::instance ()->run_reactor_event_loop (0) == -1)
        ACE_DEBUG ((LM_ERROR,
                    ACE_TEXT ("failed to handle events: \"%m\", aborting\n")));
    } // end IF
    else
      if (ACE_Proactor::instance ()->proactor_run_event_loop (0) == -1)
        ACE_DEBUG ((LM_ERROR,
                    ACE_TEXT ("failed to handle events: \"%m\", aborting\n")));
  } // end ELSE

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("finished event dispatch...\n")));

  // step8: clean up
  RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance ()->abort ();
  RPG_NET_PROTOCOL_CONNECTIONMANAGER_SINGLETON::instance ()->wait ();
  delete connector_p;
  Common_Tools::finalizeSignals (signal_set,
                                 RPG_NET_USES_REACTOR,
                                 previous_signal_actions);

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("finished working...\n")));
}