OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2011 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can | |
4 * be found in the LICENSE file. | |
5 */ | |
6 | |
7 #include "debug_conn/debug_socket.h" | |
8 #include "debug_conn/debug_socket_impl.h" | |
9 #include "debug_conn/debug_util.h" | |
10 | |
11 using namespace nacl_debug_conn; | |
12 | |
13 static const char *StateToString(DebugSocket::DSState state_) { | |
14 switch (state_) { | |
15 case DebugSocket::DSS_INVALID: return "INVALID"; | |
16 case DebugSocket::DSS_UNBOUND: return "UNBOUND"; | |
17 case DebugSocket::DSS_BOUND: return "BOUND"; | |
18 case DebugSocket::DSS_LISTEN: return "LISTEN"; | |
19 case DebugSocket::DSS_CONNECTED: return "CONNECTED"; | |
20 default: | |
21 break; | |
22 } | |
23 | |
24 return "<UNKNOWN>"; | |
25 } | |
26 | |
27 | |
28 DebugSocket::DebugSocket() | |
29 : state_(DSS_INVALID), | |
30 handle_(DEBUG_SOCKET_BAD), | |
31 msec_timeout_(1000) { | |
32 DebugSocketInit(); | |
33 } | |
34 | |
35 DebugSocket::~DebugSocket() { | |
36 if (GetHandle() != DEBUG_SOCKET_BAD) | |
37 Destruct(); | |
38 DebugSocketExit(); | |
39 } | |
40 | |
41 bool DebugSocket::Construct() { | |
42 if (state_ != DSS_INVALID) { | |
43 debug_log_error("Socket can not construct from state_ %s.\n", | |
44 StateToString( GetState() )); | |
45 return false; | |
46 } | |
47 | |
48 DSHandle handle; | |
49 if (DebugSocketCreate(&handle) == DSE_OK) { | |
50 SetState(DSS_UNBOUND); | |
51 SetHandle(handle); | |
52 return true; | |
53 } | |
54 | |
55 return false; | |
56 } | |
57 | |
58 void DebugSocket::Destruct() { | |
59 if (state_ != DSS_INVALID) { | |
60 DebugSocketClose( GetHandle() ); | |
61 } | |
62 | |
63 SetHandle(DEBUG_SOCKET_BAD); | |
64 SetState(DSS_INVALID); | |
65 } | |
66 | |
67 | |
68 DebugSocket::DSState DebugSocket::GetState() const { | |
69 return state_; | |
70 } | |
71 | |
72 void DebugSocket::SetState(DSState s) { | |
73 state_ = s; | |
74 } | |
75 | |
76 void* DebugSocket::GetHandle() const { | |
77 return handle_; | |
78 } | |
79 | |
80 void DebugSocket::SetHandle(void *h) { | |
81 handle_ = h; | |
82 } | |
83 | |
84 uint32_t DebugSocket::GetTimeout() const { | |
85 return msec_timeout_; | |
86 } | |
87 | |
88 void DebugSocket::SetTimeout(uint32_t msec) { | |
89 msec_timeout_ = msec; | |
90 } | |
91 | |
92 | |
93 | |
94 DebugSocket *DebugSocket::CreateServer(const char *addr, | |
95 int outstanding) { | |
96 DebugSocket *serv = new DebugSocket(); | |
97 serv->Construct(); | |
98 | |
99 if (DebugSocketBind(serv->GetHandle(), addr) == DSE_OK) | |
100 { | |
101 serv->SetState(DSS_BOUND); | |
102 if (DebugSocketListen(serv->GetHandle(), outstanding) == DSE_OK) { | |
103 serv->SetState(DSS_LISTEN); | |
104 return serv; | |
105 } | |
106 else | |
107 debug_log_error("Failed to listen on '%s'.\n", addr); | |
108 } | |
109 else | |
110 debug_log_error("Failed to bind server on '%s'.\n", addr); | |
111 | |
112 delete serv; | |
113 return 0; | |
114 } | |
115 | |
116 DebugSocket *DebugSocket::CreateClient(const char *addr) { | |
117 const int kMaxRetries = 20; | |
118 const int kHalfSecondSleep = 500; // millisconds to sleep | |
119 DebugSocket *client = new DebugSocket(); | |
120 client->Construct(); | |
121 int retries_left = kMaxRetries; | |
122 while (retries_left > 0) { | |
123 debug_log_info("Connecting to addr %s, retries_left=%d\n", | |
124 addr, retries_left); | |
125 if (DebugSocketConnect(client->GetHandle(), addr) == DSE_OK) { | |
126 client->SetState(DSS_CONNECTED); | |
127 return client; | |
128 } | |
129 Sleep(kHalfSecondSleep); | |
130 --retries_left; | |
131 } | |
132 | |
133 delete client; | |
134 return 0; | |
135 } | |
136 | |
137 DebugSocket *DebugSocket::Accept() { | |
138 DSHandle newHandle; | |
139 DebugSocket *newSocket; | |
140 | |
141 if (state_ != DSS_LISTEN) { | |
142 debug_log_error("Socket can not accept from state_ %s.\n", | |
143 StateToString(state_)); | |
144 return 0; | |
145 } | |
146 | |
147 if (DebugSocketAccept(GetHandle(), &newHandle, 0, 0) == DSE_OK) { | |
148 newSocket = new DebugSocket(); | |
149 newSocket->SetHandle(newHandle); | |
150 newSocket->SetState(DSS_CONNECTED); | |
151 return newSocket; | |
152 } | |
153 | |
154 return 0; | |
155 } | |
156 | |
157 int32_t DebugSocket::Read(void *ptr, int32_t len) { | |
158 if (len == 0) | |
159 return 0; | |
160 | |
161 if (DebugSocketRecv(GetHandle(), ptr, len, &len) == DSE_ERROR) { | |
162 Destruct(); | |
163 return -1; | |
164 } | |
165 | |
166 if (len == 0) { | |
167 Destruct(); | |
168 return -1; | |
169 } | |
170 | |
171 return len; | |
172 } | |
173 | |
174 int DebugSocket::Write(void *ptr, int32_t len) { | |
175 if (len == 0) | |
176 return 0; | |
177 | |
178 if (DebugSocketSend(handle_, ptr, len, &len) == DSE_ERROR) { | |
179 Destruct(); | |
180 return -1; | |
181 } | |
182 | |
183 if (len == 0) { | |
184 Destruct(); | |
185 return -1; | |
186 } | |
187 | |
188 return len; | |
189 } | |
190 | |
191 bool DebugSocket::IsConnected() const { | |
192 return GetState() == DSS_CONNECTED; | |
193 } | |
194 | |
195 bool DebugSocket::DataAvail() const { | |
196 return DebugSocketRecvAvail(GetHandle(), GetTimeout()) != DSE_TIMEOUT; | |
197 } | |
198 | |
OLD | NEW |