// $Id$ #include "LocalityActivator_Impl.h" #include "ace/Log_Msg.h" #include "ace/UUID.h" #include "dance/Logger/Log_Macros.h" #include "dance/DAnCE_PropertiesC.h" #include "tao/ORB_Core.h" #include "dance/LocalityManager/Scheduler/Plugin_Manager.h" namespace DAnCE { DAnCE_LocalityActivator_i::DAnCE_LocalityActivator_i (CORBA::ULong def_spawn_delay, const char * default_cs_path, const char * cs_args, bool multithreaded, CORBA::ORB_ptr orb, PortableServer::POA_ptr poa) : spawn_delay_ (def_spawn_delay), multithreaded_ (multithreaded), orb_ (CORBA::ORB::_duplicate (orb)), poa_ (PortableServer::POA::_duplicate (poa)), cs_path_ (default_cs_path), cs_args_ (cs_args), mutex_ (), condition_ (mutex_) { DANCE_TRACE ("DAnCE_LocalityActivator_i::DAnCE_LocalityActivator_i"); ACE_Utils::UUID_GENERATOR::instance ()->init (); // initialize the process manager with the ORBs reactor // so the exit handlers get triggered when needed this->process_manager_.open (ACE_Process_Manager::DEFAULT_SIZE, this->orb_->orb_core ()->reactor ()); } DAnCE_LocalityActivator_i::~DAnCE_LocalityActivator_i(void) { } void DAnCE_LocalityActivator_i::locality_manager_callback ( ::DAnCE::LocalityManager_ptr serverref, const char * server_UUID, ::Deployment::Properties_out config) { DANCE_TRACE("DAnCE_LocalityActivator_i::locality_manager_callback"); DANCE_DEBUG (DANCE_LOG_MINOR_EVENT, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Received callback from LocalityManager %C\n"), server_UUID)); Server_Info *info = 0; { ACE_GUARD_THROW_EX ( TAO_SYNCH_MUTEX, guard, this->container_mutex_, CORBA::NO_RESOURCES ()); for (SERVER_INFOS::iterator i (this->server_infos_.begin ()); i != this->server_infos_.end (); ++i) { DANCE_DEBUG (DANCE_LOG_DETAILED_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Comparing %C with %C\n"), (*i)->uuid_.c_str (), server_UUID)); if ((*i)->uuid_ == server_UUID) { info = (*i).get (); } } } if (!info) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_WARNING, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Received callback from LocalityManager %C, which doesn't belong to me.\n"), server_UUID)); throw ::CORBA::BAD_PARAM (); } if (info->status_ == Server_Info::ACTIVE) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Received callback from LocalityManager %C, ") ACE_TEXT ("which has already been configured.\n"), server_UUID)); throw ::CORBA::BAD_INV_ORDER (); } if (!CORBA::is_nil (info->ref_)) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Received callback from LocalityManager %C, ") ACE_TEXT ("which has already called back.\n"), server_UUID)); throw ::CORBA::BAD_INV_ORDER (); } DANCE_DEBUG (DANCE_LOG_EVENT_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Received callback from LocalityManager %C\n"), server_UUID)); info->ref_ = ::DAnCE::LocalityManager::_duplicate (serverref); this->create_properties (*info, config); // @@TODO: May want to print out configvalues here. DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::locality_manager_callback - ") ACE_TEXT ("Generated %u Properties for LocalityManager %C\n"), config->length (), server_UUID)); } void DAnCE_LocalityActivator_i::configuration_complete (const char *server_UUID) { DANCE_TRACE ("DAnCE_LocalityActivator_i::configuration_complete"); DANCE_DEBUG (DANCE_LOG_MINOR_EVENT, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::configuration_complete - ") ACE_TEXT ("Received configuration_complete from LocalityManager %C\n"), server_UUID)); try { Server_Info *info = 0; { ACE_GUARD_THROW_EX ( TAO_SYNCH_MUTEX, guard, this->container_mutex_, CORBA::NO_RESOURCES ()); for (SERVER_INFOS::iterator j (this->server_infos_.begin ()); j != this->server_infos_.end (); ++j) { if ((*j)->uuid_ == server_UUID) { info = (*j).get (); } } } if (!info) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_WARNING, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::configuration_complete - ") ACE_TEXT ("Received configuration_complete from LocalityManager %C, which doesn't belong to me.\n"), server_UUID)); throw ::CORBA::BAD_PARAM (); } if (info->status_ == Server_Info::ACTIVE) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::configuration_complete - ") ACE_TEXT ("Received configuration_complete from LocalityManager %C, ") ACE_TEXT ("which has already been completed.\n"), server_UUID)); throw ::CORBA::BAD_INV_ORDER (); } if (CORBA::is_nil (info->ref_.in ())) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::configuration_complete - ") ACE_TEXT ("Received configuration_complete from LocalityManager %C, ") ACE_TEXT ("which has not called back.\n"), server_UUID)); throw ::CORBA::BAD_INV_ORDER (); } ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, guard, info->mutex_, CORBA::NO_RESOURCES ()); info->status_ = Server_Info::ACTIVE; info->condition_.signal (); } catch (...) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::configuration_complete - ") ACE_TEXT ("Caught unknown exception while processing ") ACE_TEXT ("configuration_complete\n"))); throw; } } ::DAnCE::LocalityManager_ptr DAnCE_LocalityActivator_i::create_locality_manager (const ::Deployment::DeploymentPlan &plan, CORBA::ULong instanceRef, const ::Deployment::Properties & config) { DANCE_TRACE("DAnCE_LocalityActivator_i::create_locality_manager"); Safe_Server_Info server (new Server_Info (plan, instanceRef, config.length () + 1)); DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_locality_manager - ") ACE_TEXT ("Received %u config properties\n"), config.length ())); DAnCE::Utility::build_property_map (*server->cmap_, config); ACE_CString cmd_options = this->construct_command_line (*server); DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_locality_manager - ") ACE_TEXT ("LocalityManager arguments: %C\n"), cmd_options.c_str ())); { ACE_GUARD_THROW_EX ( TAO_SYNCH_MUTEX, guard, this->container_mutex_, CORBA::NO_RESOURCES ()); server_infos_.insert (server); } DANCE_DEBUG (DANCE_LOG_EVENT_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_locality_manager - ") ACE_TEXT ("Attempting to spawn LocalityManager with UUID %C\n"), server->uuid_.c_str ())); // Now we need to get a copy of the one that was inserted... pid_t const pid = this->spawn_locality_manager (new Server_Child_Handler (server), cmd_options); ACE_Time_Value timeout (this->spawn_delay_); CORBA::Any val; if (server->cmap_->find (DAnCE::LOCALITY_TIMEOUT, val) == 0) { CORBA::ULong t; if (val >>= t) { DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_locality_manager - ") ACE_TEXT ("Using provided non-default server timeout of %u\n"), t)); timeout = ACE_Time_Value (t); } else { DANCE_ERROR (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_WARNING, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_locality_manager - ") ACE_TEXT ("Failed to extract provided non-default server timeout ") ACE_TEXT ("from property '%C', ") ACE_TEXT ("falling back to default timeout of %u\n"), this->spawn_delay_)); } } if (this->multithreaded_) this->multi_threaded_wait_for_callback (*server, timeout); else this->single_threaded_wait_for_callback (*server, timeout); server->pid_ = pid; // register pid of successfully started lm processkate DANCE_DEBUG (DANCE_LOG_MAJOR_EVENT, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_locality_manager - ") ACE_TEXT ("LocalityManager %C successfully spawned and configured!\n"), server->uuid_.c_str ())); return ::DAnCE::LocalityManager::_duplicate (server->ref_.in ()); } ACE_CString DAnCE_LocalityActivator_i::construct_command_line (Server_Info &server) { DANCE_TRACE ("DAnCE_LocalityActivator_i::construct_command_line"); // Build our command line to launch the component server ACE_CString cmd_options (this->cs_args_); CORBA::Any val; if (server.cmap_->find (DAnCE::LOCALITY_UUID, val) == 0) { // Nodeapplication has requested a custom uuid DANCE_DEBUG (DANCE_LOG_DETAILED_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::construct_command_line - ") ACE_TEXT ("Using provided UUID\n"))); const char *uuid = 0; val >>= uuid; server.uuid_ = uuid; } else { DANCE_DEBUG (DANCE_LOG_DETAILED_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::construct_command_line - ") ACE_TEXT ("Using generated UUID\n"))); ACE_Utils::UUID uuid; ACE_Utils::UUID_GENERATOR::instance ()->generate_UUID (uuid); server.uuid_ = *uuid.to_string (); } if (server.cmap_->find (DAnCE::LOCALITY_ARGUMENTS, val) == 0) { const char *args = 0; val >>= args; DANCE_DEBUG (DANCE_LOG_DETAILED_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::construct_command_line - ") ACE_TEXT ("Adding provided server arguments %C\n"), args)); cmd_options += ' '; cmd_options += args; cmd_options += ' '; } if (server.cmap_->find (DAnCE::DANCE_LM_CONFIGFILE, val) == 0) { const char *args = 0; val >>= args; DANCE_DEBUG (DANCE_LOG_DETAILED_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::construct_command_line - ") ACE_TEXT ("Adding provided locality configuration file %C\n"), args)); cmd_options += " --plugin-config "; cmd_options += args; cmd_options += ' '; } DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::construct_command_line - ") ACE_TEXT ("Creating component server") ACE_TEXT (" with UUID %C\n"), server.uuid_.c_str ())); cmd_options += " -u "; cmd_options += server.uuid_; return cmd_options; } pid_t DAnCE_LocalityActivator_i::spawn_locality_manager (Server_Child_Handler* exit_handler, const ACE_CString &cmd_line) { DANCE_TRACE ("DAnCE_LocalityActivator_i::spawn_locality_manager"); const Server_Info &si = exit_handler->server_info (); // Get my object reference CORBA::Object_var obj = this->poa_->servant_to_reference (this); CORBA::String_var ior = this->orb_->object_to_string (obj.in ()); CORBA::Any val; const char *path = this->cs_path_.c_str (); if (si.cmap_->find (DAnCE::LOCALITY_EXECUTABLE, val) == 0) { val >>= path; DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("Using provided component server executable: %C\n"), path)); } else { DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("Using default component server executable\n"))); } ACE_Process_Options options (true, ACE_OS::strlen (path) + ACE_OS::strlen (cmd_line.c_str()) + ACE_OS::strlen (ior.in ()) + 15); if (options.command_line ("%s %s -c %s", path, cmd_line.c_str (), ior.in ()) != 0) { DANCE_ERROR (DANCE_LOG_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("Failed to create commandline\n"))); throw Deployment::StartError ("locality_manager", "Failed to create command line for server"); } options.avoid_zombies (0); // check for customized PATH addition if (si.cmap_->find (DANCE_LM_PATH, val) == 0) { path = 0; val >>= path; if (path) { ACE_CString newpath (ACE_OS::getenv ("PATH")); newpath += ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH_SEPARATOR_STR); newpath += path; options.setenv (ACE_TEXT("PATH"), ACE_TEXT_CHAR_TO_TCHAR (newpath.c_str ())); DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("configured customized PATH environment: %C\n"), newpath.c_str ())); } } // check for customized LD search path addition if (si.cmap_->find (DANCE_LM_LIBPATH, val) == 0) { path = 0; val >>= path; if (path) { ACE_CString newpath (ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH))); newpath += ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH_SEPARATOR_STR); newpath += path; options.setenv (ACE_LD_SEARCH_PATH, ACE_TEXT_CHAR_TO_TCHAR (newpath.c_str ())); DANCE_DEBUG (DANCE_LOG_MAJOR_DEBUG_INFO, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("configured customized %s environment: %C\n"), ACE_LD_SEARCH_PATH, newpath.c_str ())); } } DANCE_DEBUG (DANCE_LOG_EVENT_TRACE, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("Spawning process, command line is %s\n"), options.command_line_buf ())); pid_t const pid = this->process_manager_.spawn (options, exit_handler); if (pid == ACE_INVALID_PID) { // clean up as in this case the handler did not get registered delete exit_handler; DANCE_ERROR (DANCE_LOG_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("Failed to spawn a LocalityManager process\n"))); throw Deployment::StartError ("locality_manager", "Failed to spawn process"); } DANCE_DEBUG (DANCE_LOG_MINOR_EVENT, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::spawn_locality_manager - ") ACE_TEXT ("Process successfully spawned with pid %u\n"), pid)); return pid; } void DAnCE_LocalityActivator_i:: single_threaded_wait_for_callback (const Server_Info &si, ACE_Time_Value &timeout) { DANCE_TRACE ("DAnCE_LocalityActivator_i::single_threaded_wait_for_callback"); // Below code is broken for thread-per-connection concurrency model, // since the main thread is running ORB event loop and will spawn // a different thread to handle the call , // the operation will not be invoked and finally // a timeout will occur. For a similar reason, it won't work // for thread-pool concurrency model. while (true) { if (si.status_ != Server_Info::ACTIVE && si.status_ != Server_Info::TERMINATED) { ACE_GUARD_THROW_EX ( TAO_SYNCH_MUTEX, guard, this->mutex_, CORBA::NO_RESOURCES ()); // The next guy to acquire the mutex may have already // been activated by the previous leader's perform_work, // so let's check to make sure that only non-activated // folks are hanging on perform_work. if (si.status_ != Server_Info::ACTIVE && si.status_ != Server_Info::TERMINATED) { this->orb_->perform_work (timeout); } } if (si.status_ == Server_Info::TERMINATED) { DANCE_ERROR (DANCE_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::single_threaded_wait_for_callback - ") ACE_TEXT ("Startup failed for LocalityManager %C; process exited before activation.\n"), si.uuid_.c_str ())); throw ::Deployment::StartError ("locality_manager", "Failed to startup LocalityManager"); } if (si.status_ == Server_Info::ACTIVE) { break; } if (timeout == ACE_Time_Value::zero) { DANCE_ERROR (DANCE_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::single_threaded_wait_for_callback - ") ACE_TEXT ("Timed out while waiting for LocalityManager %C to call back.\n"), si.uuid_.c_str ())); throw ::Deployment::StartError ("locality_manager", "Timed out waiting for LocalityManager"); } } } void DAnCE_LocalityActivator_i:: multi_threaded_wait_for_callback (Server_Info &si, ACE_Time_Value &timeout) { DANCE_TRACE ("DAnCE_LocalityActivator_i::multi_threaded_wait_for_callback"); // Wait for a conditional variable ACE_GUARD_THROW_EX ( TAO_SYNCH_MUTEX, guard, si.mutex_, CORBA::NO_RESOURCES ()); while (si.status_ != Server_Info::ACTIVE) { if (si.condition_.wait (&timeout) == -1) { DANCE_ERROR (DANCE_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::multi_threaded_wait_for_callback - ") ACE_TEXT ("Timed out while waiting for LocalityManager %C to call back.\n"), si.uuid_.c_str ())); throw Deployment::StartError ("locality_manager", "timed out waiting for callback"); } if (si.status_ == Server_Info::TERMINATED) { DANCE_ERROR (DANCE_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::multi_threaded_wait_for_callback - ") ACE_TEXT ("Startup failed for LocalityManager %C; process exited before activation.\n"), si.uuid_.c_str ())); throw ::Deployment::StartError ("locality_manager", "Failed to startup LocalityManager"); } } } void DAnCE_LocalityActivator_i::remove_locality_manager (::DAnCE::LocalityManager_ptr server) { DANCE_TRACE ("DAnCE_LocalityActivator_i::remove_locality_manager"); Safe_Server_Info info; { ACE_GUARD_THROW_EX ( TAO_SYNCH_MUTEX, guard, this->container_mutex_, CORBA::NO_RESOURCES ()); SERVER_INFOS::iterator i; for (i = this->server_infos_.begin (); i != this->server_infos_.end (); ++i) { if ((!i->null ()) && (!CORBA::is_nil ((*i)->ref_)) && (*i)->ref_->_is_equivalent (server)) { info = *i; this->server_infos_.erase (i); break; } } } if (!info) { DANCE_ERROR (DANCE_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::remove_locality_manager - ") ACE_TEXT ("Failed to find equivalent LocalityManager under my management.\n"))); throw ::Deployment::StopError ("locality manager", "unable to stop locality manager"); } if (info->status_ == Server_Info::TERMINATED) { DANCE_DEBUG (DANCE_LOG_WARNING, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::remove_locality_manager - ") ACE_TEXT ("Locality Manager with UUID <%C> already terminated\n"), info->uuid_.c_str ())); return; } try { DANCE_DEBUG (DANCE_LOG_MINOR_EVENT, (LM_TRACE, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::remove_locality_manager - ") ACE_TEXT ("Calling shutdown on LocalityManager %C\n"), info->uuid_.c_str ())); info->status_ = Server_Info::TERMINATE_REQUESTED; server->shutdown (); } catch (::Deployment::StopError &) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_WARNING, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::remove_locality_manager - ") ACE_TEXT ("Received RemoveFailure exception from LocalityManager %C\n"), info->uuid_.c_str ())); } DANCE_DEBUG (DANCE_LOG_MAJOR_EVENT, (LM_INFO, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::remove_locality_manager - ") ACE_TEXT ("LocalityManager %C successfully shut down.\n"), info->uuid_.c_str ())); } void DAnCE_LocalityActivator_i::create_properties ( const Server_Info &info, Deployment::Properties_out config) { DANCE_DEBUG (DANCE_LOG_TRACE, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::create_properties - ") ACE_TEXT ("Creating property sequence for LocalityManager <%C> with ") ACE_TEXT ("length %u\n"), info.uuid_.c_str (), info.cmap_->current_size ())); if (info.cmap_->current_size () == 0) return; ACE_NEW_THROW_EX (config, Deployment::Properties (info.cmap_->current_size ()), CORBA::NO_MEMORY ()); config->length (info.cmap_->current_size ()); CORBA::ULong pos = 0; Utility::PROPERTY_MAP::iterator i = info.cmap_->begin (); do { config[pos].name = i->ext_id_.c_str (); config[pos].value = i->int_id_; ++pos; } while (i.advance () != 0); } DAnCE_LocalityActivator_i::Server_Child_Handler::Server_Child_Handler ( const Safe_Server_Info& si) : server_info_ (si) {} DAnCE_LocalityActivator_i::Server_Child_Handler::~Server_Child_Handler () { } int DAnCE_LocalityActivator_i::Server_Child_Handler::handle_close ( ACE_HANDLE, ACE_Reactor_Mask) { DANCE_DEBUG (DANCE_LOG_DETAILED_TRACE, (LM_DEBUG, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::Server_Child_Handler::handle_close\n"))); delete this; // clean us up return 0; } int DAnCE_LocalityActivator_i::Server_Child_Handler::handle_exit ( ACE_Process *proc) { DANCE_DEBUG (DANCE_LOG_MINOR_EVENT, (LM_INFO, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::Server_Child_Handler::handle_exit") ACE_TEXT (" - Locality Manager UUID %C, pid=%d: %d\n"), this->server_info_->uuid_.c_str (), int (proc->getpid ()), int (proc->exit_code ()) )); // this method is guarenteed to be called synchronously // so we can safely call anything we like // Check if the termination was requested, log an error if not. if (this->server_info_->status_ != Server_Info::TERMINATE_REQUESTED) { DANCE_ERROR (DANCE_LOG_NONFATAL_ERROR, (LM_ERROR, DLINFO ACE_TEXT ("DAnCE_LocalityActivator_i::Server_Child_Handler::handle_exit - ") ACE_TEXT ("Error: Unexpected locality shutdown.\n"))); const DAnCE::Plugin_Manager::INTERCEPTORS &interceptors = PLUGIN_MANAGER::instance ()->fetch_interceptors (); for (Plugin_Manager::INTERCEPTORS::const_iterator i = interceptors.begin (); i != interceptors.end (); ++i) { try { ::CORBA::Any tmp; (*i)->unexpected_event (this->server_info_->plan_, this->server_info_->instanceRef_, tmp, "Unexpected component server exit."); } catch (...) { // swallow } } } // flag this process as exited this->server_info_->status_ = Server_Info::TERMINATED; // signal possibly waiting startup thread this->server_info_->condition_.signal (); return 0; } }