X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_init_listener.cpp;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_init_listener.cpp;h=700df8b9f50581859a40e1b0c8e510a7675c2712;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/hdsd/scd/scd_init_listener.cpp b/dol/src/dol/visitor/hdsd/scd/scd_init_listener.cpp new file mode 100644 index 0000000..700df8b --- /dev/null +++ b/dol/src/dol/visitor/hdsd/scd/scd_init_listener.cpp @@ -0,0 +1,126 @@ +#include "scd_init_listener.h" + +#include "scd_logging.h" +#include "scd_exception.h" +#include "scd_in_connector.h" + + +scd_init_listener::scd_init_listener(scd_simulator &sim, uint16_t port): + _sim(sim), _host(""), _port(port), _handler(false) {} + + +scd_init_listener::scd_init_listener(scd_simulator &sim, + const std::string &host, uint16_t port): + _sim(sim), _host(host), _port(port), _handler(false) {} + + +scd_init_listener::~scd_init_listener() +{ + cleanup(true); + close(); +} + + +void scd_init_listener::listen() +{ + if (!_socket.is_valid()) + { + // create listening socket + if (!_socket.create()) + throw scd_exception("creating listening socket failed"); + if (!_socket.bind(_host, _port)) + throw scd_exception("binding listening socket failed"); + if (!_socket.listen()) + throw scd_exception("listening to socket failed"); + + // register socket + if (!_handler) + { + _sim.get_poller().register_handler(*this, + SOCK_EV_READ | SOCK_EV_CLOSE); + _handler = true; + } + + scd_debug("socket listening"); + } + else + scd_warn("socket is already listening"); + +} // listen() + + +void scd_init_listener::close() +{ + if (_handler) + { + _sim.get_poller().remove_handler(*this); + _handler = false; + } + + if (_socket.is_valid()) + { + _socket.close(); + scd_debug("listener socket closed"); + } + +} // close() + + +void scd_init_listener::cleanup(bool hard) +{ + std::list::iterator iter; + + for( iter=_connectors.begin(); iter!=_connectors.end();) + { + if ( hard || !(*iter)->is_connecting() ) + { + delete *iter; + iter = _connectors.erase(iter); + } + else + iter++; + } +} // cleanup() + + +void scd_init_listener::handle_sock_ev(sock_ev events) +{ + if (events & SOCK_EV_READ) + { + scd_debug("incomming connection"); + + scd_socket* newconn = new scd_socket(); + + if (_socket.accept(*newconn)) + { + /* create a new connector that handles the connection + * and store it in the list of connectors */ + scd_in_connector* connector; + connector = new scd_in_connector(_sim, newconn); + _connectors.push_back(connector); + } + else + { + // connection could not be accepted + scd_debug("accepting connection failed"); + delete newconn; + } + } + + if (events & SOCK_EV_CLOSE) + { + throw scd_exception("init_listener: experienced an error"); + } + + if (!_socket.is_valid()) + { + throw scd_exception("init_listener: unexpectedly closed"); + } + +} // sock_ev_handler() + + +const scd_socket& scd_init_listener::get_sock() +{ + return _socket; +}