server.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 788 行 · 第 1/2 页
CPP
788 行
AssetMap::iterator i;
for (i = m_assets.begin (); i != m_assets.end (); i++) {
afile << i->first << endl;
if (!afile) {
cerr << "Cannot update " << m_asset_file.in () << endl;
assert (0);
}
delete i->second;
}
//afile.close ();
//if (!afile) {
// cerr << "Cannot close " << m_asset_file << endl;
// assert (0);
//}
}
CCS::Thermometer_ptr
Controller_impl::
create_thermometer (CCS::AssetType anum, const char * loc)
throw (CORBA::SystemException, CCS::Controller::DuplicateAsset)
{
if (anum % 2 == 0)
throw CORBA::BAD_PARAM (); // Thermometers have odd numbers
if (exists (anum))
throw CCS::Controller::DuplicateAsset ();
assert (ICP_online (anum) == 0);
assert (ICP_set (anum, "location", loc) == 0);
add_impl (anum, 0);
return make_dref (m_poa.in (), anum);
}
CCS::Thermostat_ptr
Controller_impl::
create_thermostat (
CCS::AssetType anum,
const char* loc,
CCS::TempType temp)
throw (
CORBA::SystemException,
CCS::Controller::DuplicateAsset,
CCS::Thermostat::BadTemp)
{
if (anum % 2 != 0)
throw CORBA::BAD_PARAM (); // Thermostats have even numbers
if (exists (anum))
throw CCS::Controller::DuplicateAsset ();
assert (ICP_online (anum) == 0);
assert (ICP_set (anum, "location", loc) == 0);
// Set the nominal temperature.
if (ICP_set (anum, "nominal_temp", &temp) != 0) {
// If ICP_set () failed, read this thermostat's minimum
// and maximum so we can initialize the BadTemp exception.
CCS::Thermostat::BtData btd;
ICP_get (
anum, "MIN_TEMP",
&btd.min_permitted, sizeof (btd.min_permitted)
);
ICP_get (
anum, "MAX_TEMP",
&btd.max_permitted, sizeof (btd.max_permitted)
);
btd.requested = temp;
btd.error_msg = CORBA::string_dup (
temp > btd.max_permitted ? "Too hot" : "Too cold"
);
ICP_offline (anum);
throw CCS::Thermostat::BadTemp (btd);
}
add_impl (anum, 0);
CORBA::Object_var obj = make_dref (m_poa.in (), anum);
return CCS::Thermostat::_narrow (obj.in ());
}
// IDL list operation.
CCS::Controller::ThermometerSeq *
Controller_impl::
list () throw (CORBA::SystemException)
{
// Create a new thermometer sequence. Because we know
// the number of elements we will put onto the sequence,
// we use the maximum constructor.
CCS::Controller::ThermometerSeq_var listv
= new CCS::Controller::ThermometerSeq (m_assets.size ());
listv->length (m_assets.size ());
// Loop over the m_assets set and create a
// reference for each device.
CORBA::ULong count = 0;
AssetMap::iterator i;
for (i = m_assets.begin (); i != m_assets.end (); i++)
listv[count++] = make_dref (m_poa.in (), i->first);
return listv._retn ();
}
// IDL change operation.
void
Controller_impl::
change (
const CCS::Controller::ThermostatSeq & tlist,
CORBA::Short delta
) throw (CORBA::SystemException, CCS::Controller::EChange)
{
CCS::Controller::EChange ec; // Just in case we need it
// We cannot add a delta value to a thermostat's temperature
// directly, so for each thermostat, we read the nominal
// temperature, add the delta value to it, and write
// it back again.
for (CORBA::ULong i = 0; i < tlist.length (); i++) {
if (CORBA::is_nil (tlist[i]))
continue; // Skip nil references
// Read nominal temp and update it.
CCS::TempType tnom = tlist[i]->get_nominal ();
tnom += delta;
try {
tlist[i]->set_nominal (tnom);
}
catch (const CCS::Thermostat::BadTemp &bt) {
// If the update failed because the temperature
// is out of range, we add the thermostat's info
// to the errors sequence.
CORBA::ULong len = ec.errors.length ();
ec.errors.length (len + 1);
ec.errors[len].tmstat_ref = tlist[i].in ();
ec.errors[len].info = bt.details;
}
}
// If we encountered errors in the above loop,
// we will have added elements to the errors sequence.
if (ec.errors.length () != 0)
throw ec;
}
// IDL find operation
void
Controller_impl::
find (CCS::Controller::SearchSeq & slist)
throw (CORBA::SystemException)
{
// Loop over input list and lookup each device.
CORBA::ULong listlen = slist.length ();
for (CORBA::ULong i = 0; i < listlen; i++) {
AssetMap::iterator where; // Iterator for asset set
int num_found = 0; // Num matched per iteration
// Assume we will not find a matching device.
slist[i].device = CCS::Thermometer::_nil ();
// Work out whether we are searching by asset,
// model, or location.
CCS::Controller::SearchCriterion sc = slist[i].key._d ();
if (sc == CCS::Controller::ASSET) {
// Search for matching asset number.
where = m_assets.find (slist[i].key.asset_num ());
if (where != m_assets.end ())
slist[i].device = make_dref (m_poa.in (), where->first);
} else {
// Search for model or location string.
const char *search_str;
if (sc == CCS::Controller::LOCATION)
search_str = slist[i].key.loc ();
else
search_str = slist[i].key.model_desc ();
// Find first matching device (if any).
where = find_if (
m_assets.begin (), m_assets.end (),
StrFinder (sc, search_str)
);
// While there are matches...
while (where != m_assets.end ()) {
if (num_found == 0) {
// First match overwrites reference
// in search record.
slist[i].device = make_dref (m_poa.in (), where->first);
} else {
// Further matches each append a new
// element to the search sequence.
CORBA::ULong len = slist.length ();
slist.length (len + 1);
slist[len].key = slist[i].key;
slist[len].device = make_dref (m_poa.in (), where->first);
}
num_found++;
// Find next matching device with this key.
where = find_if (
++where, m_assets.end (),
StrFinder (sc, search_str)
);
}
}
}
}
//----------------------------------------------------------------
DeviceLocator_impl::
DeviceLocator_impl (Controller_impl * ctrl) : m_ctrl (ctrl)
{
// Intentionally empty
}
PortableServer::Servant
DeviceLocator_impl::
preinvoke (
const PortableServer::ObjectId & oid,
PortableServer::POA_ptr /* poa */,
const char * operation,
void * & /* cookie */
) throw (CORBA::SystemException, PortableServer::ForwardRequest)
{
// Convert object id into asset number.
CORBA::String_var oid_string;
try {
oid_string = PortableServer::ObjectId_to_string (oid);
} catch (const CORBA::BAD_PARAM &) {
throw CORBA::OBJECT_NOT_EXIST ();
}
if (strcmp (oid_string.in (), Controller_oid) == 0)
return m_ctrl;
istrstream istr (oid_string.in ());
CCS::AssetType anum;
istr >> anum;
if (istr.fail ())
throw CORBA::OBJECT_NOT_EXIST ();
// Check whether the device is known.
if (!m_ctrl->exists (anum))
throw CORBA::OBJECT_NOT_EXIST ();
// Look at the object map to find out whether
// we have a servant in memory.
Thermometer_impl * servant;
ActiveObjectMap::iterator servant_pos = m_aom.find (anum);
if (servant_pos == m_aom.end ()) {
// No servant in memory. If evictor queue is full,
// evict servant at head of queue.
if (m_eq.size () == MAX_EQ_SIZE) {
servant = m_eq.back ();
m_aom.erase (servant->m_anum);
m_eq.pop_back ();
delete servant;
}
// Instantiate correct type of servant.
char buf[32];
assert (ICP_get (anum, "model", buf, sizeof (buf)) == 0);
if (strcmp (buf, "Sens-A-Temp") == 0)
servant = new Thermometer_impl (anum);
else
servant = new Thermostat_impl (anum);
} else {
// Servant already in memory.
servant = * (servant_pos->second); // Remember servant
m_eq.erase (servant_pos->second); // Remove from queue
// If operation is "remove", also remove entry from
// active object map -- the object is about to be deleted.
if (strcmp (operation, "remove") == 0)
m_aom.erase (servant_pos);
}
// We found a servant, or just instantiated it.
// If the operation is not a remove, move
// the servant to the tail of the evictor queue
// and update its queue position in the map.
if (strcmp (operation, "remove") != 0) {
m_eq.push_front (servant);
m_aom[anum] = m_eq.begin ();
}
return servant;
}
//----------------------------------------------------------------
int
main (int argc, char * argv[])
{
CORBA::ORB_var orb;
try {
// Initialize orb
orb = CORBA::ORB_init (argc, argv);
// Get reference to Root POA.
CORBA::Object_var obj
= orb->resolve_initial_references ("RootPOA");
PortableServer::POA_var poa
= PortableServer::POA::_narrow (obj.in ());
// Get POA manager
PortableServer::POAManager_var poa_mgr = poa->the_POAManager ();
// Create a policy list. We use persistent objects with
// user-assigned IDs, and explicit activation.
CORBA::PolicyList policy_list;
policy_list.length (6);
policy_list[0] = poa->create_lifespan_policy (
PortableServer::TRANSIENT // REVISIT
);
policy_list[1] = poa->create_id_assignment_policy (
PortableServer::USER_ID
);
policy_list[2] = poa->create_implicit_activation_policy (
PortableServer::NO_IMPLICIT_ACTIVATION
);
policy_list[3] = poa->create_request_processing_policy (
PortableServer::USE_SERVANT_MANAGER
);
policy_list[4] = poa->create_servant_retention_policy (
PortableServer::NON_RETAIN
);
policy_list[5] = poa->create_thread_policy (
PortableServer::SINGLE_THREAD_MODEL
);
// Create a POA for all CCS elements.
PortableServer::POA_var ccs_poa
= poa->create_POA ("CCS_POA", poa_mgr.in (), policy_list);
// Create a controller and set static m_ctrl member
// for thermostats and thermometers.
Controller_impl ctrl_servant (ccs_poa.in (), "/tmp/CCS_assets");
Thermometer_impl::m_ctrl = &ctrl_servant;
// Create a reference for the controller and
// create the corresponding CORBA object.
PortableServer::ObjectId_var oid
= PortableServer::string_to_ObjectId (Controller_oid);
CORBA::Object_var ctrl
= ccs_poa->create_reference_with_id (
oid.in (), "IDL:acme.com/CCS/Controller:1.0"
);
// Get reference to initial naming context.
CosNaming::NamingContext_var inc
= resolve_init<CosNaming::NamingContext> (
orb.in (), "NameService"
);
// Attempt to create CCS context.
CosNaming::Name n;
n.length (1);
n[0].id = CORBA::string_dup ("CCS");
try {
CosNaming::NamingContext_var nc
= inc->bind_new_context (n);
} catch (const CosNaming::NamingContext::AlreadyBound &) {
// Fine, CCS context already exists.
}
// Force binding of controller reference to make
// sure it is always up-to-date.
n.length (2);
n[1].id = CORBA::string_dup ("Controller");
inc->rebind (n, ctrl.in ());
// Instantiate the servant locator for devices.
PortableServer::ServantManager_var locator =
new DeviceLocator_impl (&ctrl_servant);
// Set servant locator.
ccs_poa->set_servant_manager (locator.in ());
// Activate the POA manager.
poa_mgr->activate ();
// Accept requests
orb->run ();
}
catch (const CORBA::Exception & e) {
cerr << "Uncaught CORBA exception: " << e << endl;
return 1;
}
catch (...) {
assert (0); // Uncaught exception, dump core
}
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?