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 + -
显示快捷键?