X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_cont_man_slave.cpp;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_cont_man_slave.cpp;h=7368ef98a91469cb3911b23b5de58fd6c94cb717;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.cpp b/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.cpp new file mode 100644 index 0000000..7368ef9 --- /dev/null +++ b/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.cpp @@ -0,0 +1,181 @@ +#include "scd_cont_man_slave.h" + +#include "scd_logging.h" +#include "scd_exception.h" + + +scd_cont_man_slave::scd_cont_man_slave(scd_simulator& sim): + scd_cont_fsm("slave"), _sim(sim), + _connector(sim, SCD_CM_NETSIM, sim.get_name()), _has_master(false), + _st_init(sim, *this), _st_busy(sim, *this), _st_fail(sim, *this), + _st_failed(sim, *this), _st_idle(sim, *this), _st_done(sim, *this), + _st_time_ack(sim, *this), _st_time(sim, *this), _st_term_ack(sim, *this), + _st_terminated(sim, *this) +{ + // set initial state + set_state(_st_init); +} + + +scd_cont_man_slave::~scd_cont_man_slave() +{ + if (_socket != NULL) + delete _socket; +} + + +void scd_cont_man_slave::set_socket() +{ + _socket = _connector.get_connection(); + _writer.set_socket(*_socket); + _reader.set_socket(*_socket); +} // set_socket() + + +void scd_cont_man_slave::send_command(scd_command* cmd) +{ + // register write event if not registered + if (!_writer.is_writing() && _socket->is_valid()) + _sim.get_poller().set_ev(*this, SOCK_EV_WRITE | SOCK_EV_READ + | SOCK_EV_CLOSE); + + // queue command to be written + _writer.queue_command(cmd); +} + + +bool scd_cont_man_slave::is_sending() +{ + return _writer.is_writing() && _socket->is_valid(); +} + + +void scd_cont_man_slave::close() +{ + if (_socket != NULL) + _socket->close(); +} + + +void scd_cont_man_slave::set_master(const std::string& host, uint16_t port) +{ + if (!_has_master) + _connector.connect_to(host, port); + else + { + scd_error("master already set"); + throw scd_exception("master already set"); + } +} // set_master() + + +void scd_cont_man_slave::register_slave(const std::string& name) +{ + scd_error("simulator is slave, can not have other slaves"); + throw scd_exception("simulator is slave"); + +} // register_slave + + +void scd_cont_man_slave::handle_sock_ev(sock_ev events) +{ + scd_sts_base& state = *static_cast(_state); + + if (events & SOCK_EV_CLOSE) + { + scd_error("connection to master lost"); + _socket->close(); + state.set_failed(); + return; + } + + if (events & SOCK_EV_READ) + { + _reader.read(); + + if (!_socket->is_valid()) + { + // connection closed + scd_error("connection to master lost"); + state.set_failed(); + return; + } + + if (!_reader.is_reading() && !_reader.has_command()) + { + // received an illegal command + scd_error("received illegal command"); + state.set_fail(); + return; + } + + if (_reader.has_command()) + { + scd_command* cmd = _reader.get_command(); + _process_cmd(*cmd); + delete cmd; + } + + } // end read event + + if (events & SOCK_EV_WRITE) + { + _writer.write(); + if (!_writer.is_writing()) + { + // done sending commands + _sim.get_poller().set_ev(*this, SOCK_EV_READ | SOCK_EV_CLOSE); + } + } // end write event + + if (!_socket->is_valid()) + { + scd_error("connection to master lost"); + state.set_failed(); + } + +} // handle_sock_ev() + + +const scd_socket& scd_cont_man_slave::get_sock() { return *_socket; } + + +void scd_cont_man_slave::_process_cmd(scd_command& cmd) +{ + if (cmd.get_type() != SCD_CM_CONTROL) + { + scd_warn("received non-control command"); + return; + } + + scd_sts_base* state = static_cast(_state); + + switch (cmd.get_subtype()) + { + case SCD_CM_FAILED: + scd_error("master failed"); + state->set_failed(); + break; + case SCD_CM_TIME_REQ: + state->recv_time_req(); + break; + case SCD_CM_TIME_NACK: + state->recv_time_nack(); + break; + case SCD_CM_TIME: + state->recv_time(cmd.get_time()); + break; + case SCD_CM_TERM_REQ: + state->recv_term_req(); + break; + case SCD_CM_TERM_NACK: + state->recv_term_nack(); + break; + case SCD_CM_TERM: + state->recv_term(); + break; + default: + scd_warn("received unknown command"); + break; + } +} // _process_cmd()