dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / scd_chan_man.cpp
1 #include "scd_chan_man.h"
2
3 #include "scd_logging.h"
4
5
6 scd_chan_man::scd_chan_man(scd_simulator &sim):
7     _sim(sim), _is_ready(false) {}
8
9
10 scd_chan_man::~scd_chan_man()
11 {
12     std::list<scd_out_connector*>::iterator coit;
13     std::list<scd_chan_wrapper*>::iterator chit;
14
15     for (coit = _connectors.begin(); coit != _connectors.end(); coit++)
16         delete *coit;
17
18     for (chit = _channels.begin(); chit != _channels.end(); chit++)
19         delete *chit;
20 }
21
22
23 void scd_chan_man::register_channel(const std::string &name, sc_prim_channel& mchan)
24 {
25     if ( _get_channel(name) != NULL )
26     {
27         scd_warn("channel \"" + name + "\" already registered, ignoring...");
28     }
29     else
30     {
31         scd_chan_wrapper* wrap = new scd_chan_wrapper(_sim, name, mchan);
32         _channels.push_back(wrap);
33     }
34
35 } // register_channel() - master
36
37
38 void scd_chan_man::register_channel(const std::string &name,
39         sc_prim_channel& schan, const std::string &host, const uint16_t port)
40 {
41     if ( _get_channel(name) != NULL )
42     {
43         scd_warn("channel \"" + name + "\" already registered, ignoring...");
44     }
45     else
46     {
47         // register channel
48         scd_chan_wrapper* wrap = new scd_chan_wrapper(_sim, name, schan);
49         _channels.push_back(wrap);
50
51         // create connector
52         scd_out_connector* conn = new scd_out_connector(_sim, SCD_CM_CHANNEL,
53                 name);
54         conn->connect_to(host, port);
55         _connectors.push_back(conn);
56     }
57
58 } // register_channel() - slave
59
60
61 void scd_chan_man::init_process()
62 {
63     if (_is_ready)
64         return;
65
66     std::list<scd_out_connector*>::iterator coit;
67
68     // check all connectors
69     for (coit = _connectors.begin(); coit != _connectors.end();)
70     {
71         scd_out_connector& conn = **coit;
72
73         // retry to connect if necessary
74         conn.process();
75
76         if (!conn.is_connecting() && !conn.has_connection())
77         {
78             // an error occured
79             scd_error("failed to connect channel \""
80                     + conn.get_name() + "\"");
81
82             delete *coit;
83             coit = _connectors.erase(coit);
84
85             _sim.get_cont_man().set_fail();
86             return;
87         }
88         else if (!conn.is_connecting() && conn.has_connection())
89         {
90             // channel is connected
91             scd_chan_wrapper& chan = *_get_channel(conn.get_name());
92
93             if (chan.is_initialized())
94             {
95                 scd_error("channel \""
96                         + conn.get_name() + "\" already connected");
97
98                 delete *coit;
99                 coit = _connectors.erase(coit);
100
101                 _sim.get_cont_man().set_fail();
102                 return;
103             }
104             else
105             {
106                 scd_info("connected channel \"" + conn.get_name() + "\"");
107                 chan.connect(conn.get_connection());
108
109                 delete *coit;
110                 coit = _connectors.erase(coit);
111             }
112         } // end channel connected
113         else
114         {
115             // still trying to connect
116             coit++;
117         }
118         // end this connector
119     } // end check all connectors
120
121     // check if everything is initiated
122     _check_ready();
123
124 } // init_process()
125
126
127 void scd_chan_man::connect_channel(const scd_command &c, scd_socket* sock)
128 {
129     std::string name = c.get_string();
130
131     scd_chan_wrapper* chan = _get_channel(name);
132
133     if (chan == NULL)
134     {
135         scd_warn("unknown channel \"" + name + "\" supplied by peer");
136         delete sock;
137     }
138     else if (chan->is_initialized())
139     {
140         scd_warn("channel \"" + name + "\" supplied by peer already connected");
141     }
142     else
143     {
144         scd_info("connected channel \"" + name + "\"");
145         chan->connect(sock);
146     }
147     
148 } // connect()
149
150
151 bool scd_chan_man::ready() const { return _is_ready; }
152
153
154 void scd_chan_man::process()
155 {
156     std::list<scd_chan_wrapper*>::iterator chit;
157
158     for (chit = _channels.begin(); chit != _channels.end(); chit++)
159         (*chit)->process();
160
161 } // process()
162
163
164 void scd_chan_man::close()
165 {
166     std::list<scd_out_connector*>::iterator coit;
167     std::list<scd_chan_wrapper*>::iterator chit;
168
169     for (coit = _connectors.begin(); coit != _connectors.end(); coit++)
170         (*coit)->close();
171
172     for (chit = _channels.begin(); chit != _channels.end(); chit++)
173         (*chit)->close();
174
175 } // close()
176
177
178 bool scd_chan_man::_check_ready()
179 {
180     if (_is_ready)
181         return true;
182
183     if (_connectors.empty())
184     {
185         std::list<scd_chan_wrapper*>::iterator chit;
186
187         // check all channels
188         for (chit = _channels.begin(); chit != _channels.end(); chit++)
189         {
190             if ( !(*chit)->is_initialized() )
191                 return false;
192         }
193
194         // all channels initiated
195         _is_ready = true;
196         return true;
197     }
198     else
199         return false;
200
201 } // _check_ready()
202
203
204 scd_chan_wrapper* scd_chan_man::_get_channel(const std::string& name)
205 {
206     std::list<scd_chan_wrapper*>::iterator chit;
207
208     for (chit = _channels.begin(); chit != _channels.end(); chit++)
209     {
210         if ( (*chit)->get_name() == name )
211             return *chit;
212     }
213
214     return NULL;
215
216 } // _get_channel()