X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_chan_man.cpp;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_chan_man.cpp;h=d98e8ea77dfcd6da976725d3795eb70f17bb2843;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/hdsd/scd/scd_chan_man.cpp b/dol/src/dol/visitor/hdsd/scd/scd_chan_man.cpp new file mode 100644 index 0000000..d98e8ea --- /dev/null +++ b/dol/src/dol/visitor/hdsd/scd/scd_chan_man.cpp @@ -0,0 +1,216 @@ +#include "scd_chan_man.h" + +#include "scd_logging.h" + + +scd_chan_man::scd_chan_man(scd_simulator &sim): + _sim(sim), _is_ready(false) {} + + +scd_chan_man::~scd_chan_man() +{ + std::list::iterator coit; + std::list::iterator chit; + + for (coit = _connectors.begin(); coit != _connectors.end(); coit++) + delete *coit; + + for (chit = _channels.begin(); chit != _channels.end(); chit++) + delete *chit; +} + + +void scd_chan_man::register_channel(const std::string &name, sc_prim_channel& mchan) +{ + if ( _get_channel(name) != NULL ) + { + scd_warn("channel \"" + name + "\" already registered, ignoring..."); + } + else + { + scd_chan_wrapper* wrap = new scd_chan_wrapper(_sim, name, mchan); + _channels.push_back(wrap); + } + +} // register_channel() - master + + +void scd_chan_man::register_channel(const std::string &name, + sc_prim_channel& schan, const std::string &host, const uint16_t port) +{ + if ( _get_channel(name) != NULL ) + { + scd_warn("channel \"" + name + "\" already registered, ignoring..."); + } + else + { + // register channel + scd_chan_wrapper* wrap = new scd_chan_wrapper(_sim, name, schan); + _channels.push_back(wrap); + + // create connector + scd_out_connector* conn = new scd_out_connector(_sim, SCD_CM_CHANNEL, + name); + conn->connect_to(host, port); + _connectors.push_back(conn); + } + +} // register_channel() - slave + + +void scd_chan_man::init_process() +{ + if (_is_ready) + return; + + std::list::iterator coit; + + // check all connectors + for (coit = _connectors.begin(); coit != _connectors.end();) + { + scd_out_connector& conn = **coit; + + // retry to connect if necessary + conn.process(); + + if (!conn.is_connecting() && !conn.has_connection()) + { + // an error occured + scd_error("failed to connect channel \"" + + conn.get_name() + "\""); + + delete *coit; + coit = _connectors.erase(coit); + + _sim.get_cont_man().set_fail(); + return; + } + else if (!conn.is_connecting() && conn.has_connection()) + { + // channel is connected + scd_chan_wrapper& chan = *_get_channel(conn.get_name()); + + if (chan.is_initialized()) + { + scd_error("channel \"" + + conn.get_name() + "\" already connected"); + + delete *coit; + coit = _connectors.erase(coit); + + _sim.get_cont_man().set_fail(); + return; + } + else + { + scd_info("connected channel \"" + conn.get_name() + "\""); + chan.connect(conn.get_connection()); + + delete *coit; + coit = _connectors.erase(coit); + } + } // end channel connected + else + { + // still trying to connect + coit++; + } + // end this connector + } // end check all connectors + + // check if everything is initiated + _check_ready(); + +} // init_process() + + +void scd_chan_man::connect_channel(const scd_command &c, scd_socket* sock) +{ + std::string name = c.get_string(); + + scd_chan_wrapper* chan = _get_channel(name); + + if (chan == NULL) + { + scd_warn("unknown channel \"" + name + "\" supplied by peer"); + delete sock; + } + else if (chan->is_initialized()) + { + scd_warn("channel \"" + name + "\" supplied by peer already connected"); + } + else + { + scd_info("connected channel \"" + name + "\""); + chan->connect(sock); + } + +} // connect() + + +bool scd_chan_man::ready() const { return _is_ready; } + + +void scd_chan_man::process() +{ + std::list::iterator chit; + + for (chit = _channels.begin(); chit != _channels.end(); chit++) + (*chit)->process(); + +} // process() + + +void scd_chan_man::close() +{ + std::list::iterator coit; + std::list::iterator chit; + + for (coit = _connectors.begin(); coit != _connectors.end(); coit++) + (*coit)->close(); + + for (chit = _channels.begin(); chit != _channels.end(); chit++) + (*chit)->close(); + +} // close() + + +bool scd_chan_man::_check_ready() +{ + if (_is_ready) + return true; + + if (_connectors.empty()) + { + std::list::iterator chit; + + // check all channels + for (chit = _channels.begin(); chit != _channels.end(); chit++) + { + if ( !(*chit)->is_initialized() ) + return false; + } + + // all channels initiated + _is_ready = true; + return true; + } + else + return false; + +} // _check_ready() + + +scd_chan_wrapper* scd_chan_man::_get_channel(const std::string& name) +{ + std::list::iterator chit; + + for (chit = _channels.begin(); chit != _channels.end(); chit++) + { + if ( (*chit)->get_name() == name ) + return *chit; + } + + return NULL; + +} // _get_channel()