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); }
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"))); }