// // Главное приложение примера. // // Создает подсистему SO SysConf 2 и организует интерактивный // диалог с оператором. // // Демонстрирует два способа журналирования состояния SO SysConf 2: // - назначение подсистеме SO SysConf 2 журнализатора; // - прослушивание сообщений // so_sysconf_2::a_sysconf_t::msg_sysconf_info. // #include <iostream> #include <memory> #include <sstream> // Загружаем средства поддержки многопоточности. #include <ace/OS.h> #include <ace/Thread_Manager.h> // Загружаем необходимые заголовочные файлы SObjectizer. #include <so_4/rt/h/rt.hpp> #include <so_4/rt/h/msg_auto_ptr.hpp> #include <so_4/api/h/api.hpp> #include <so_4/timer_thread/simple/h/pub.hpp> #include <so_4/disp/one_thread/h/pub.hpp> // Загружаем описание агента a_sysconf_t для доступа // к его сообщениям. #include <so_sysconf_2/h/a_sysconf.hpp> // Загружаем описание журнализатора в std::ostream // для печати изменений состояния SO SysConf 2 на // стандартный поток вывода. #include <so_sysconf_2/h/ostream_sysconf_logger.hpp> // Средства запуска SO SysConf 2. #include <so_sysconf_2/h/pub.hpp> // // a_sysconf_listener_t // /* Агент, который будет слушать состояние sysconf. Для этого агент подписывается на сообщение so_sysconf_2::a_sysconf_t::msg_sysconf_info. Агент a_sysconf_listener будет создаваться до того, как будет запущена подсистема sysconf. Поэтому агент a_sysconf_listener должен подписываться на сообщение msg_sysconf_info только после запуска sysconf. Для этого агенту a_sysconf_listener после старта sysconf нужно отослать сообщение a_sysconf_listener_t::msg_subscr. */ class a_sysconf_listener_t : public so_4::rt::agent_t { typedef so_4::rt::agent_t base_type_t; public : a_sysconf_listener_t(); virtual ~a_sysconf_listener_t(); const char * so_query_type() const; void so_on_subscription(); // Имя единственного агента данного типа. static const std::string & agent_name(); // Сообщение, дающее команду агенту подписаться // на сообщение msg_sysconf_info. struct msg_subscr { }; // Обработчик изменения состояния sysconf. void evt_sysconf_info( const so_4::rt::event_data_t & data, const so_sysconf_2::a_sysconf_t::msg_sysconf_info * cmd ); // Подписка на сообщение msg_sysconf_info. void evt_subscr( const so_4::rt::event_data_t & data, const msg_subscr * cmd ); }; SOL4_CLASS_START( a_sysconf_listener_t ) SOL4_MSG_START( msg_subscr, a_sysconf_listener_t::msg_subscr ) SOL4_MSG_FINISH() SOL4_EVENT_WITH_INCIDENT_TYPE( evt_sysconf_info, so_sysconf_2::a_sysconf_t::msg_sysconf_info ) SOL4_EVENT_WITH_INCIDENT_TYPE( evt_subscr, a_sysconf_listener_t::msg_subscr ) SOL4_STATE_START( st_normal ) SOL4_STATE_EVENT( evt_sysconf_info ) SOL4_STATE_EVENT( evt_subscr ) SOL4_STATE_FINISH() SOL4_CLASS_FINISH() a_sysconf_listener_t::a_sysconf_listener_t() : base_type_t( agent_name().c_str() ) { } a_sysconf_listener_t::~a_sysconf_listener_t() { } void a_sysconf_listener_t::so_on_subscription() { // Сразу можно подписаться только на // собственное сообщение. SOL4_SUBSCR_EVENT_START( evt_subscr, 0 ) SOL4_SUBSCR_EVENT_MSG_SELF( "msg_subscr" ) SOL4_SUBSCR_EVENT_FINISH_CERR() } const std::string & a_sysconf_listener_t::agent_name() { static const std::string name( "a_sysconf_listener" ); return name; } void a_sysconf_listener_t::evt_sysconf_info( const so_4::rt::event_data_t & data, const so_sysconf_2::a_sysconf_t::msg_sysconf_info * cmd ) { std::ostringstream out; // Начинается распечатка текущего состояния. out << "*** sysconf info begin ***\n"; // Просмотр всех загруженных sysconf-ом DLL. const so_sysconf_2::dll_info_set_t & dlls = cmd->m_info.query_dlls(); for( so_sysconf_2::dll_info_set_t::const_iterator it_dll = dlls.begin(), it_dll_end = dlls.end(); it_dll != it_dll_end; ++it_dll ) { // То, что известно про DLL. out << it_dll->query_alias() << " (file_name: " << it_dll->query_file_name() << ", ref_count: " << it_dll->query_ref_count() << ")\n"; // Просмотр всех коопераций, находящихся // в данной DLL. const so_sysconf_2::coop_info_set_t & coops = it_dll->query_coops(); for( so_sysconf_2::coop_info_set_t::const_iterator it_coop = coops.begin(), it_coop_end = coops.end(); it_coop != it_coop_end; ++it_coop ) { // То, что известно про кооперацию. out << "\tcooperation: " << it_coop->query_coop_name(); if( it_coop->is_reg() ) out << ", registered"; out << "\n"; } // Просмотр всех фабрик, находящихся // в данной DLL. const so_sysconf_2::factory_info_set_t & factories = it_dll->query_factories(); for( so_sysconf_2::factory_info_set_t::const_iterator it_factory = factories.begin(), it_factory_end = factories.end(); it_factory != it_factory_end; ++it_factory ) { // То, что известно про фабрику. out << "\tfactory: " << it_factory->query_factory_name() << "\n"; } } out << "*** sysconf info end ***\n"; // Распечатка текущего состояния завершена. std::cout << out.str() << std::endl; } void a_sysconf_listener_t::evt_subscr( const so_4::rt::event_data_t & data, const msg_subscr * ) { SOL4_SUBSCR_EVENT_START( evt_sysconf_info, 0 ) SOL4_SUBSCR_EVENT_MSG( so_sysconf_2::a_sysconf_t::agent_name(), "msg_sysconf_info" ) SOL4_SUBSCR_EVENT_FINISH_CERR() } // // Нить, на которой будет происходить запуск SObjectizer-а // ACE_THR_FUNC_RETURN sobjectizer_thread( void * ) { // Используется простой таймер. std::auto_ptr< so_4::timer_thread::timer_thread_t > timer_ptr( so_4::timer_thread::simple::create_timer_thread() ); // Используется простой диспетчер с одной рабочей нитью. std::auto_ptr< so_4::rt::dispatcher_t > disp_ptr( so_4::disp::one_thread::create_disp( *timer_ptr ) ); // В стартовую кооперацию будет входить только слушатель // состояния подсистемы sysconf. a_sysconf_listener_t a_listener; so_4::rt::agent_coop_t coop( a_listener ); so_4::ret_code_t rc = so_4::api::start( *disp_ptr, &coop ); if( rc ) { // Запуск SObjectizer не удался. std::cerr << "start: " << rc << std::endl; } return 0; } int main( int argc, char ** argv ) { // Запускаем SObjectizer. ACE_Thread_Manager::instance()->spawn( &sobjectizer_thread ); // Даем время SObjectizer для старта. ACE_OS::sleep( 1 ); // Цикл интерактивного взаимодействия с оператором. bool is_continue = true; while( is_continue ) { // Задержка для отладочных печатей. ACE_Time_Value pause( 0, 250000 ); ACE_OS::sleep( pause ); std::string choice; std::cout << "Choose action:\n" "\t0 - quit\n" "\t1 - create sysconf cooperation\n" "\t2 - parse config file\n" "\t3 - send msg_reg_coop\n" "\t4 - send msg_dereg_coop\n" "\t5 - send msg_load_dll\n" "\t6 - send msg_unload_dll\n" "\t7 - send msg_query_sysconf_info\n" "\t8 - send msg_make_coop\n" "\t9 - send msg_event\n" "\t10 - send msg_restart_coop\n" "\t11 - send msg_rereg_coop\n" << std::flush; std::cin >> choice; if( !std::cin ) choice = "0"; if( choice == "0" ) { // Необходимо завершить работу примера. so_4::api::send_msg( so_4::rt::sobjectizer_agent_name(), "msg_normal_shutdown", 0, so_4::rt::sobjectizer_agent_name() ); is_continue = false; } else if( choice == "1" ) { // Стартуем подсистему sysconf. so_sysconf_2::register_coop( new so_sysconf_2::ostream_sysconf_logger_t() ); // Указываем слушателю на необходимость // начать прослушивать состояние sysconf. so_4::api::send_msg( a_sysconf_listener_t::agent_name(), "msg_subscr", 0 ); } else if( choice == "2" ) { // Запрашиваем имя конфигурационного файла... std::string config_file_name; std::cout << "Enter config file name: " << std::flush; std::cin >> config_file_name; // ... и инициируем обработку этого файла. so_sysconf_2::run_script( config_file_name ); } else if( choice == "3" ) { // Подготавливаем сообщение-команду регистрации // кооперации. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_reg_coop > msg( new so_sysconf_2::a_sysconf_t::msg_reg_coop() ); std::cout << "Enter coop_name: " << std::flush; std::cin >> msg->m_coop_name; std::cout << "Enter cfg_file: " << std::flush; std::cin >> msg->m_cfg_file; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_reg_coop" ); } else if( choice == "4" ) { // Подготавливаем сообщение-команду дерегистрации // кооперации. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_dereg_coop > msg( new so_sysconf_2::a_sysconf_t:: msg_dereg_coop() ); std::cout << "Enter coop_name: " << std::flush; std::cin >> msg->m_coop_name; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_dereg_coop" ); } else if( choice == "5" ) { // Подготавливаем сообщение-команду загрузки DLL. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_load_dll > msg( new so_sysconf_2::a_sysconf_t::msg_load_dll() ); std::cout << "Enter dll_name: " << std::flush; std::cin >> msg->m_dll_name; std::cout << "Enter dll_alias: " << std::flush; std::cin >> msg->m_dll_alias; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_load_dll" ); } else if( choice == "6" ) { // Подготавливаем сообщение-команду выгрузки DLL. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_unload_dll > msg( new so_sysconf_2::a_sysconf_t::msg_unload_dll() ); std::cout << "Enter dll_alias: " << std::flush; std::cin >> msg->m_dll_alias; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_unload_dll" ); } else if( choice == "7" ) { // Выдаем команду sysconf-у на информирование // о своем текущем состоянии. so_4::api::send_msg( so_sysconf_2::a_sysconf_t::agent_name(), "msg_query_sysconf_info", 0 ); } else if( choice == "8" ) { // Подготавливаем сообщение-команду создания // кооперации при помощи фабрики. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_make_coop > msg( new so_sysconf_2::a_sysconf_t::msg_make_coop() ); std::cout << "Enter factory_name: " << std::flush; std::cin >> msg->m_factory_name; std::cout << "Enter coop_name: " << std::flush; std::cin >> msg->m_coop_name; std::cout << "Enter cfg_file: " << std::flush; std::cin >> msg->m_cfg_file; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_make_coop" ); } else if( choice == "9" ) { so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_event > msg( new so_sysconf_2::a_sysconf_t::msg_event() ); std::cout << "Enter event_name: " << std::flush; std::cin >> msg->m_event_name; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_event" ); } else if( choice == "10" ) { // Подготавливаем сообщение-команду перерегистрации // кооперации. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_restart_coop > msg( new so_sysconf_2::a_sysconf_t:: msg_restart_coop() ); std::cout << "Enter coop_name: " << std::flush; std::cin >> msg->m_coop_name; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_restart_coop" ); } else if( choice == "11" ) { // Подготавливаем сообщение-команду перерегистрации // кооперации с новым конфигом. so_4::rt::msg_auto_ptr_t< so_sysconf_2::a_sysconf_t::msg_rereg_coop > msg( new so_sysconf_2::a_sysconf_t:: msg_rereg_coop() ); std::cout << "Enter coop_name: " << std::flush; std::cin >> msg->m_coop_name; std::cout << "Enter cfg_file: " << std::flush; std::cin >> msg->m_cfg_file; // Отдаем команду. msg.send( so_sysconf_2::a_sysconf_t::agent_name(), "msg_rereg_coop" ); } } // Ожидаем окончательного завершения работы SObjectizer. ACE_Thread_Manager::instance()->wait(); return 0; }
Документация по so_sysconf_2 v.2.4.0. Последние изменения: Wed Oct 31 18:55:07 2007. Создано системой 1.5.4 |