dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / scd_init_listener.cpp
1 #include "scd_init_listener.h"
2
3 #include "scd_logging.h"
4 #include "scd_exception.h"
5 #include "scd_in_connector.h"
6
7
8 scd_init_listener::scd_init_listener(scd_simulator &sim, uint16_t port):
9     _sim(sim), _host(""), _port(port), _handler(false) {}
10
11
12 scd_init_listener::scd_init_listener(scd_simulator &sim,
13         const std::string &host, uint16_t port):
14     _sim(sim), _host(host), _port(port), _handler(false) {}
15
16
17 scd_init_listener::~scd_init_listener()
18 {
19     cleanup(true);
20     close();
21 }
22
23
24 void scd_init_listener::listen()
25 {
26     if (!_socket.is_valid())
27     {
28         // create listening socket
29         if (!_socket.create())
30             throw scd_exception("creating listening socket failed");
31         if (!_socket.bind(_host, _port))
32             throw scd_exception("binding listening socket failed");
33         if (!_socket.listen())
34             throw scd_exception("listening to socket failed");
35
36         // register socket
37         if (!_handler)
38         {
39             _sim.get_poller().register_handler(*this,
40                     SOCK_EV_READ | SOCK_EV_CLOSE);
41             _handler = true;
42         }
43
44         scd_debug("socket listening");
45     }
46     else
47         scd_warn("socket is already listening");
48
49 } // listen()
50
51
52 void scd_init_listener::close()
53 {
54     if (_handler)
55     {
56         _sim.get_poller().remove_handler(*this);
57         _handler = false;
58     }
59
60     if (_socket.is_valid())
61     {
62         _socket.close();
63         scd_debug("listener socket closed");
64     }
65
66 } // close()
67
68
69 void scd_init_listener::cleanup(bool hard)
70 {
71     std::list<scd_in_connector*>::iterator iter;
72
73     for( iter=_connectors.begin(); iter!=_connectors.end();)
74     {
75         if ( hard || !(*iter)->is_connecting() )
76         {
77             delete *iter;
78             iter = _connectors.erase(iter);
79         }
80         else
81             iter++;
82     }
83 } // cleanup()
84
85
86 void scd_init_listener::handle_sock_ev(sock_ev events)
87 {
88     if (events & SOCK_EV_READ)
89     {
90         scd_debug("incomming connection");
91
92         scd_socket* newconn = new scd_socket();
93
94         if (_socket.accept(*newconn))
95         {
96             /* create a new connector that handles the connection
97              * and store it in the list of connectors */
98             scd_in_connector* connector;
99             connector = new scd_in_connector(_sim, newconn);
100             _connectors.push_back(connector);
101         }
102         else
103         {
104             // connection could not be accepted
105             scd_debug("accepting connection failed");
106             delete newconn;
107         }
108     }
109     
110     if (events & SOCK_EV_CLOSE)
111     {
112         throw scd_exception("init_listener: experienced an error");
113     }
114
115     if (!_socket.is_valid())
116     {
117         throw scd_exception("init_listener: unexpectedly closed");
118     }
119
120 } // sock_ev_handler()
121
122
123 const scd_socket& scd_init_listener::get_sock()
124 {
125     return _socket;
126 }