server.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 768 行 · 第 1/2 页
CPP
768 行
// server.cpp,v 1.5 2003/11/22 23:21:31 parsons Exp
// ============================================================================
//
// = LIBRARY
// TAO/examples/Advanced/ch_21
//
// = FILENAME
// server.cpp
//
// = AUTHORS
// Source code used in TAO has been modified and adapted from the code
// provided in the book, "Advanced CORBA Programming with C++" by Michi
// Henning and Steve Vinoski. Copyright 1999. Addison-Wesley, Reading,
// MA.
//
// Modified for TAO by Mike Moran <mm4@cs.wustl.edu>
//
// ============================================================================
#include "server.h"
#include <algorithm>
#include "icp.h"
#include <ace/Synch_T.h>
#include <strstream>
#include <iostream>
#include <fstream>
using namespace std;
const char* Controller_oid = "Controller";
//----------------------------------------------------------------
// Generic ostream inserter for exceptions. Inserts the exception
// name, if available, and the repository ID otherwise.
#if 0 // This inserter is not needed for TAO.
static ostream &
operator<< (ostream & os, const CORBA::Exception & e)
{
CORBA::Any tmp;
tmp <<= e;
CORBA::TypeCode_var tc = tmp.type ();
const char * p = tc->name ();
if (*p != '\0')
os << p;
else
os << tc->id ();
return os;
}
#endif
//----------------------------------------------------------------
// Helper function to create object references.
static CCS::Thermometer_ptr make_dref (PortableServer::POA_ptr poa, CCS::AssetType anum)
{
// Convert asset number to OID.
ostrstream ostr;
ostr << anum << ends;
char * anum_str = ostr.str ();
PortableServer::ObjectId_var oid
= PortableServer::string_to_ObjectId (anum_str);
delete[] anum_str;
// Look at the model via the network to determine
// the repository ID.
char buf[32];
assert (ICP_get (anum, "model", buf, sizeof (buf)) == 0);
const char * rep_id = strcmp (buf, "Sens-A-Temp") == 0
? "IDL:acme.com/CCS/Thermometer:1.0"
: "IDL:acme.com/CCS/Thermostat:1.0";
// Make a new reference.
CORBA::Object_var obj
= poa->create_reference_with_id (oid.in (), rep_id);
return CCS::Thermometer::_narrow (obj.in ());
}
//----------------------------------------------------------------
Controller_impl * Thermometer_impl::m_ctrl; // static member
// Helper function to read the model string from a device.
CCS::ModelType
Thermometer_impl::
get_model ()
{
char buf[32];
assert (ICP_get (m_anum, "model", buf, sizeof (buf)) == 0);
return CORBA::string_dup (buf);
}
// Helper function to read the temperature from a device.
CCS::TempType
Thermometer_impl::
get_temp ()
{
short temp;
assert (ICP_get (m_anum, "temperature", &temp, sizeof (temp)) == 0);
return temp;
}
// Helper function to read the location from a device.
CCS::LocType
Thermometer_impl::
get_loc ()
{
char buf[32];
assert (ICP_get (m_anum, "location", buf, sizeof (buf)) == 0);
return CORBA::string_dup (buf);
}
// Helper function to set the location of a device.
void
Thermometer_impl::
set_loc (const char * loc)
{
assert (ICP_set (m_anum, "location", loc) == 0);
}
// Constructor.
Thermometer_impl::
Thermometer_impl (CCS::AssetType anum) :
m_anum (anum), m_ref_count (1), m_removed (false)
{
m_ctrl->add_impl (anum); // Add self to controller's set
}
// Destructor.
Thermometer_impl::
~Thermometer_impl ()
{
if (m_removed)
assert (ICP_offline (m_anum) == 0);
}
void
Thermometer_impl::_add_ref ()
{
ACE_Guard<ACE_Mutex> guard (m_count_mutex);
m_ref_count++;
}
void
Thermometer_impl::_remove_ref ()
{
bool del = false;
{
ACE_Guard<ACE_Mutex> guard (m_count_mutex);
if (--m_ref_count == 0)
del = true;
}
if (del)
delete this;
}
// IDL model attribute.
CCS::ModelType
Thermometer_impl::
model () throw (CORBA::SystemException)
{
return get_model ();
}
// IDL asset_num attribute.
CCS::AssetType
Thermometer_impl::
asset_num () throw (CORBA::SystemException)
{
return m_anum;
}
// IDL temperature attribute.
CCS::TempType
Thermometer_impl::
temperature () throw (CORBA::SystemException)
{
return get_temp ();
}
// IDL location attribute accessor.
CCS::LocType
Thermometer_impl::
location () throw (CORBA::SystemException)
{
return get_loc ();
}
// IDL remove operation.
void
Thermometer_impl::
remove () throw (CORBA::SystemException)
{
m_removed = true;
_remove_ref ();
}
// IDL location attribute modifier.
void
Thermometer_impl::
location (const char *loc) throw (CORBA::SystemException)
{
set_loc (loc);
}
//----------------------------------------------------------------
// Helper function to get a thermostat's nominal temperature.
CCS::TempType
Thermostat_impl::
get_nominal_temp ()
{
short temp;
assert (ICP_get (m_anum, "nominal_temp", &temp, sizeof (temp)) == 0);
return temp;
}
// Helper function to set a thermostat's nominal temperature.
CCS::TempType
Thermostat_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.
assert (
ICP_get (
m_anum, "nominal_temp", &old_temp, sizeof (old_temp)
) == 0
);
// Now set the nominal temperature to the new value.
if (ICP_set (m_anum, "nominal_temp", &new_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 (
m_anum, "MIN_TEMP",
&btd.min_permitted, sizeof (btd.min_permitted)
);
ICP_get (
m_anum, "MAX_TEMP",
&btd.max_permitted, sizeof (btd.max_permitted)
);
btd.requested = new_temp;
btd.error_msg = CORBA::string_dup (
new_temp > btd.max_permitted ? "Too hot" : "Too cold"
);
throw CCS::Thermostat::BadTemp (btd);
}
return old_temp;
}
// Constructor.
Thermostat_impl::
Thermostat_impl (CCS::AssetType anum) : Thermometer_impl (anum)
{
// Intentionally empty.
}
// Destructor.
Thermostat_impl::
~Thermostat_impl ()
{
// Intentionally empty.
}
// IDL get_nominal operation.
CCS::TempType
Thermostat_impl::
get_nominal () throw (CORBA::SystemException)
{
return get_nominal_temp ();
}
// IDL set_nominal operation.
CCS::TempType
Thermostat_impl::
set_nominal (CCS::TempType new_temp)
throw (CORBA::SystemException, CCS::Thermostat::BadTemp)
{
return set_nominal_temp (new_temp);
}
//----------------------------------------------------------------
// Helper function to add an entry to the asset map.
void
Controller_impl::
add_impl (CCS::AssetType anum)
{
m_assets.insert (anum);
}
// Helper function to remove an entry from the asset map.
void
Controller_impl::
remove_impl (CCS::AssetType anum)
{
m_assets.erase (anum);
}
// Helper function to locate a servant in the asset map.
bool
Controller_impl::
exists (CCS::AssetType anum)
{
return m_assets.find (anum) != m_assets.end ();
}
// Constructor
Controller_impl::
Controller_impl (PortableServer::POA_ptr poa, const char * asset_file)
throw (int) : m_poa (PortableServer::POA::_duplicate (poa)),
m_asset_file (asset_file)
{
fstream afile (m_asset_file.in (), ios::in|ios::out, 0666);
if (!afile) {
cerr << "Cannot open " << m_asset_file.in () << endl;
throw 0;
}
CCS::AssetType anum;
while (afile >> anum)
m_assets.insert (anum);
// afile.close ();
// if (!afile) {
// cerr << "Cannot close " << m_asset_file.in () << endl;
// throw 0;
// }
}
// Destructor
Controller_impl::
~Controller_impl ()
{
// Write out the current set of asset numbers
// and clean up all servant instances.
ofstream afile (m_asset_file.in ());
if (!afile) {
cerr << "Cannot open " << m_asset_file.in () << endl;
assert (0);
}
AssetSet::iterator i;
for (i = m_assets.begin (); i != m_assets.end (); i++) {
afile << *i << endl;
if (!afile) {
cerr << "Cannot update " << m_asset_file.in () << endl;
assert (0);
}
}
// afile.close ();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?