📄 server.cpp
字号:
#include <OB/CORBA.h>#include <algorithm>#include <signal.h>#include <string>#ifdef HAVE_FSTREAM# include <fstream>#else# include <fstream.h>#endif#if defined(HAVE_STD_IOSTREAM) || defined(HAVE_STD_STL)using namespace std;#endif#include "icp.h"#include "server.h"//----------------------------------------------------------------// Helper function to write a stringified reference to a file.voidwrite_ref(const char * filename, const char * reference){ ofstream file(filename); if (!file) { string msg("Error opening "); msg += filename; throw msg.c_str(); } file << reference << endl; if (!file) { string msg("Error writing "); msg += filename; throw msg.c_str(); } file.close(); if (!file) { string msg("Error closing "); msg += filename; throw msg.c_str(); }}//----------------------------------------------------------------Controller_impl * Thermometer_impl::m_ctrl; // static member// Helper function to read the model string from a device.CCS::ModelTypeThermometer_impl::get_model(){ char buf[32]; if (ICP_get(m_anum, "model", buf, sizeof(buf)) != 0) abort(); return CORBA::string_dup(buf);}// Helper function to read the temperature from a device.CCS::TempTypeThermometer_impl::get_temp(){ short temp; if (ICP_get(m_anum, "temperature", &temp, sizeof(temp)) != 0) abort(); return temp;}// Helper function to read the location from a device.CCS::LocTypeThermometer_impl::get_loc(){ // MISSING, step 4 return 0; // Replace this with the correct code}// Helper function to set the location of a device.voidThermometer_impl::set_loc(const char * loc){ if (ICP_set(m_anum, "location", loc) != 0) abort();}// Constructor.Thermometer_impl::Thermometer_impl( CCS::AssetType anum, const char * location) : m_anum(anum){ if (ICP_online(anum) != 0) // Mark device as on-line abort(); set_loc(location); // Set its location m_ctrl->add_impl(anum, this); // Add self to controller's map}// Destructor.Thermometer_impl::~Thermometer_impl(){ try { m_ctrl->remove_impl(m_anum); // Remove self from map ICP_offline(m_anum); // Mark device as off-line } catch (...) { abort(); // Prevent exceptions from escaping }}// IDL model attribute.CCS::ModelTypeThermometer_impl::model() throw(CORBA::SystemException){ return get_model();}// IDL asset_num attribute.CCS::AssetTypeThermometer_impl::asset_num() throw(CORBA::SystemException){ return m_anum;}// IDL temperature attribute.CCS::TempTypeThermometer_impl::temperature() throw(CORBA::SystemException){ return get_temp();}// IDL location attribute accessor.CCS::LocTypeThermometer_impl::location() throw(CORBA::SystemException){ // MISSING, step 4 return 0; // Replace this with the correct code}// IDL location attribute modifier.voidThermometer_impl::location(const char * loc) throw(CORBA::SystemException){ set_loc(loc);}//----------------------------------------------------------------// Helper function to get a thermostat's nominal temperature.CCS::TempTypeThermostat_impl::get_nominal_temp(){ short temp; if (ICP_get(m_anum, "nominal_temp", &temp, sizeof(temp)) != 0) abort(); return temp;}// Helper function to set a thermostat's nominal temperature.CCS::TempTypeThermostat_impl::set_nominal_temp(CCS::TempType new_temp)throw(CCS::Thermostat::BadTemp){ short old_temp; // We need to return the previous nominal temperature, // so we first read the current nominal temperature before // changing it. if (ICP_get( m_anum, "nominal_temp", &old_temp, sizeof(old_temp) ) != 0) { abort(); } // MISSING, step 5 return old_temp;}// Constructor.Thermostat_impl::Thermostat_impl( CCS::AssetType anum, const char * location, CCS::TempType nominal_temp) : Thermometer_impl(anum, location){ // Base Thermometer_impl constructor does most of the // work, so we need only set the nominal temperature here. set_nominal_temp(nominal_temp);}// IDL get_nominal operation.CCS::TempTypeThermostat_impl::get_nominal() throw(CORBA::SystemException){ return get_nominal_temp();}// IDL set_nominal operation.CCS::TempTypeThermostat_impl::set_nominal(CCS::TempType new_temp)throw(CORBA::SystemException, CCS::Thermostat::BadTemp){ return set_nominal_temp(new_temp);}//----------------------------------------------------------------// Helper function for thermometers and thermostats to// add themselves to the m_assets map.voidController_impl::add_impl(CCS::AssetType anum, Thermometer_impl * tip){ m_assets[anum] = tip;}// Helper function for thermometers and thermostats to// remove themselves from the m_assets map.voidController_impl::remove_impl(CCS::AssetType anum){ m_assets.erase(anum);}// IDL list operation.CCS::Controller::ThermometerSeq *Controller_impl::list() throw(CORBA::SystemException){ // MISSING, step 6 return 0; // Replace this with the correct code}// IDL change operation.voidController_impl::change( const CCS::Controller::ThermostatSeq & tlist, CORBA::Short delta) throw(CORBA::SystemException, CCS::Controller::EChange){ // MISSING, step 7}// IDL find operationvoidController_impl::find(CCS::Controller::SearchSeq & slist)throw(CORBA::SystemException){ // MISSING, step 8}//----------------------------------------------------------------voidrun(CORBA::ORB_ptr orb){ // Get reference to Root POA. CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow(obj); // Create a controller and set static m_ctrl member // for thermostats and thermometers. Controller_impl ctrl_servant; Thermometer_impl::m_ctrl = &ctrl_servant; // Write controller stringified reference to ctrl.ref. CCS::Controller_var ctrl = ctrl_servant._this(); CORBA::String_var str = orb->object_to_string(ctrl); write_ref("ctrl.ref", str); // Create a few devices. (Thermometers have odd asset // numbers, thermostats have even asset numbers.) Thermometer_impl thermo1(2029, "Deep Thought"); Thermometer_impl thermo2(8053, "HAL"); Thermometer_impl thermo3(1027, "ENIAC"); Thermostat_impl tmstat1(3032, "Colossus", 68); Thermostat_impl tmstat2(4026, "ENIAC", 60); Thermostat_impl tmstat3(4088, "ENIAC", 50); Thermostat_impl tmstat4(8042, "HAL", 40); // Write a thermostat reference to tmstat.ref. CCS::Thermostat_var tmstat = tmstat1._this(); str = orb->object_to_string(tmstat); write_ref("tmstat.ref", str); // Activate POA manager PortableServer::POAManager_var mgr = poa->the_POAManager(); mgr->activate(); // Accept requests orb->run();}//----------------------------------------------------------------static CORBA::ORB_var orb; // Global, so handler can see it.//----------------------------------------------------------------#ifdef WIN32BOOLhandler(DWORD){ // Inform JTC of presence of new thread JTCAdoptCurrentThread adopt; // Terminate event loop try { if (!CORBA::is_nil(orb)) orb->shutdown(false); } catch (...) { // Can't throw here... } return TRUE;}#elseextern "C"voidhandler(int){ // Ignore further signals struct sigaction ignore; ignore.sa_handler = SIG_IGN; sigemptyset(&ignore.sa_mask); ignore.sa_flags = 0; if (sigaction(SIGINT, &ignore, (struct sigaction *)0) == -1) abort(); if (sigaction(SIGTERM, &ignore, (struct sigaction *)0) == -1) abort(); if (sigaction(SIGHUP, &ignore, (struct sigaction *)0) == -1) abort(); // Terminate event loop try { if (!CORBA::is_nil(orb)) orb->shutdown(false); } catch (...) { // Can't throw here... }}#endif//----------------------------------------------------------------intmain(int argc, char* argv[]){ // Install signal handler for cleanup#ifdef WIN32 BOOL rc = SetConsoleCtrlHandler((PHANDLER_ROUTINE)handler, TRUE); if (!rc) abort();#else struct sigaction sa; // New signal state sa.sa_handler = handler; // Set handler function sigfillset(&sa.sa_mask); // Mask all other signals // while handler runs sa.sa_flags = 0 | SA_RESTART; // Restart interrupted syscalls if (sigaction(SIGINT, &sa, (struct sigaction *)0) == -1) abort(); if (sigaction(SIGHUP, &sa, (struct sigaction *)0) == -1) abort(); if (sigaction(SIGTERM, &sa, (struct sigaction *)0) == -1) abort();#endif // Initialize the ORB and start working... int status = 0; try { orb = CORBA::ORB_init(argc, argv); run(orb); } catch (const CORBA::Exception & ex) { cerr << "Uncaught CORBA exception: " << ex << endl; status = 1; } catch (...) { cerr << "Uncaught non-CORBA exception" << endl; status = 1; } // Destroy the ORB. if (!CORBA::is_nil(orb)) { try { orb->destroy(); } catch (const CORBA::Exception & ex) { cerr << "Cannot destroy ORB: " << ex << endl; status = 1; } } return status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -