-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_vm.cpp
193 lines (149 loc) · 4.9 KB
/
test_vm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <ace/INET_Addr.h>
#include <ace/SOCK.h>
#include <map>
#include <memory>
#include <iostream>
enum Peer_State
{
AVAILABLE = 0,
CONNECTED,
NUM_STATES
};
bool is_valid(Peer_State state)
{
return ((AVAILABLE <= state) && (state < NUM_STATES));
}
struct Action_Context
{
};
struct Peer_Info
{
ACE_INET_Addr addr;
ACE_SOCK *connection;
Peer_State state;
Peer_Info()
: connection(NULL), state(AVAILABLE) {}
Peer_Info(ACE_INET_Addr _addr)
: addr(_addr), connection(NULL), state(AVAILABLE) {}
};
struct Peer_Addr
{
u_int32_t ip;
short port;
Peer_Addr(u_int32_t _ip, short _port)
: ip(_ip), port(_port) {}
};
inline
bool operator<(const Peer_Addr &addr1, const Peer_Addr &addr2)
{
return
(addr1.ip != addr2.ip) ?
(addr1.ip < addr2.ip) :
(addr1.port < addr2.port);
}
typedef std::map<Peer_Addr, Peer_Info> Peer_Store_t;
Peer_Store_t peer_store;
class Peer_SM
{
public:
enum Peer_Actions
{
OPEN_CONNECTION = 0,
CLOSE_CONNECTION,
HANDLE_REQUEST,
HANDLE_RESPONSE,
NUM_ACTIONS
};
static bool is_valid_action(Peer_Actions action)
{
return ((OPEN_CONNECTION <= action) && (action < NUM_ACTIONS));
}
static void do_action(const Peer_Addr &address, Peer_Actions action, const Action_Context &context)
{
if (is_valid_action(action))
{
Peer_Store_t::iterator peer_iter = peer_store.find(address);
if (peer_iter != peer_store.end())
{
Peer_Info &peer_info = peer_iter->second;
Peer_State current_state = peer_info.state;
if (is_valid(current_state))
{
SM_Action_t act = actions_map[current_state][action];
Peer_State new_state = states_map[current_state][action];
if (act(peer_info, context))
{
peer_info.state = new_state;
}
}
}
}
}
private:
typedef bool (*SM_Action_t)(Peer_Info &, const Action_Context &);
static Peer_State states_map[NUM_STATES][NUM_ACTIONS];
static SM_Action_t actions_map[NUM_STATES][NUM_ACTIONS];
static bool no_operation(Peer_Info &, const Action_Context &);
static bool open_connection(Peer_Info &, const Action_Context &);
static bool close_connection(Peer_Info &, const Action_Context &);
static bool hanle_request(Peer_Info &, const Action_Context &);
static bool handle_response(Peer_Info &, const Action_Context &);
};
Peer_State Peer_SM::states_map[NUM_STATES][Peer_SM::NUM_ACTIONS] = {
// OPEN_CONNECTION CLOSE_CONNECTION HANDLE_REQUEST HANDLE_RESPONSE
{CONNECTED, AVAILABLE, AVAILABLE, AVAILABLE}, // AVAILABLE
{CONNECTED, AVAILABLE, CONNECTED, CONNECTED}, // CONNECTED
};
Peer_SM::SM_Action_t Peer_SM::actions_map[NUM_STATES][Peer_SM::NUM_ACTIONS] = {
// OPEN_CONNECTION CLOSE_CONNECTION HANDLE_REQUEST HANDLE_RESPONSE
{Peer_SM::open_connection, Peer_SM::no_operation, Peer_SM::no_operation, Peer_SM::no_operation}, // AVAILABLE
{Peer_SM::no_operation, Peer_SM::close_connection, Peer_SM::hanle_request, Peer_SM::handle_response}, // CONNECTED
};
bool Peer_SM::no_operation(Peer_Info &info, const Action_Context &context)
{
std::cout << "no_op with " << info.addr.get_host_addr() << std::endl;
return true;
}
bool Peer_SM::open_connection(Peer_Info &info, const Action_Context &context)
{
std::cout << "open connection with " << info.addr.get_host_addr() << std::endl;
return true;
}
bool Peer_SM::close_connection(Peer_Info &info, const Action_Context &context)
{
std::cout << "close connection with " << info.addr.get_host_addr() << std::endl;
info.connection->close();
return true;
}
bool Peer_SM::hanle_request(Peer_Info &info, const Action_Context &context)
{
std::cout << "handle request from " << info.addr.get_host_addr() << std::endl;
return true;
}
bool Peer_SM::handle_response(Peer_Info &info, const Action_Context &context)
{
std::cout << "send response to " << info.addr.get_host_addr() << std::endl;
return true;
}
int main()
{
ACE_INET_Addr addr("127.0.0.1:456");
ACE_INET_Addr addr1("10.245.65.13:65");
peer_store[Peer_Addr(1,1)] = Peer_Info(addr);
peer_store[Peer_Addr(1,2)] = Peer_Info(addr1);
Peer_Info &info = peer_store[Peer_Addr(1,2)];
Peer_SM::Peer_Actions actions[] =
{
Peer_SM::CLOSE_CONNECTION,
Peer_SM::HANDLE_REQUEST,
Peer_SM::OPEN_CONNECTION,
Peer_SM::HANDLE_REQUEST,
Peer_SM::HANDLE_RESPONSE,
Peer_SM::OPEN_CONNECTION,
Peer_SM::CLOSE_CONNECTION,
};
Action_Context context;
for (int i = 0; i < 7; ++i)
Peer_SM::do_action(Peer_Addr(1,2), actions[i], context);
return 0;
}