Now you can download a copy of these docs so you can use them offline! Download now
ClientConnectionAdapter.cpp
1 /*
2  * ClientConnectionAdapter.cpp
3  *
4  * Created on: Nov 2, 2012
5  * Author: Mitchell Wills
6  */
7 
8 #include "networktables2/client/ClientConnectionAdapter.h"
9 #include "networktables2/util/System.h"
10 
11 void ClientConnectionAdapter::gotoState(ClientConnectionState* newState){
12  {
13  NTSynchronized sync(LOCK);
14  if(connectionState!=newState){
15  fprintf(stdout, "[NT] %p entered connection state: %s\n", (void*)this, newState->toString());
16  fflush(stdout);
18  connectionListenerManager.FireConnectedEvent();
19  if(connectionState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
20  connectionListenerManager.FireDisconnectedEvent();
21  //TODO find better way to manage memory leak
22  ClientConnectionState_Error *temp=dynamic_cast<ClientConnectionState_Error *>(connectionState);
23  connectionState = newState;
24  if (temp)
25  delete temp;
26  }
27  }
28 }
33  return connectionState;
34 }
40 }
41 
51  entryStore(_entryStore),
52  streamFactory(_streamFactory),
53  threadManager(_threadManager),
54  connectionListenerManager(_connectionListenerManager),
55  typeManager(_typeManager),
56  readThread(NULL),
57  monitor(NULL),
58  connection(NULL){
60 }
61 ClientConnectionAdapter::~ClientConnectionAdapter()
62 {
63  if(readThread!=NULL)
64  readThread->stop();
65  if (connection)
66  connection->close();
67  if(readThread!=NULL)
68  {
69  delete readThread;
70  readThread = NULL;
71  }
72  if(monitor!=NULL)
73  {
74  delete monitor;
75  monitor = NULL;
76  }
77  close();
78  if(connection!=NULL){
79  delete connection;
80  connection = NULL;
81  }
82 
83  //TODO find better way to manage memory leak
84  ClientConnectionState_Error *temp=dynamic_cast<ClientConnectionState_Error *>(connectionState);
85  if (temp)
86  {
87  delete temp;
88  connectionState=NULL;
89  }
90 }
91 
92 
93 /*
94  * Connection management
95  */
100  //This is in reconnect so that the entry store doesn't have to be valid when this object is deleted
101  //Note: clearIds() cannot be in a LOCK critical section
102  entryStore.clearIds();
103  {
104  NTSynchronized sync(LOCK);
105  close();//close the existing stream and monitor thread if needed
106  try{
107  IOStream* stream = streamFactory.createStream();
108  if(stream==NULL)
109  return;
110  if (!connection)
111  connection = new NetworkTableConnection(stream, typeManager);
112  else
113  connection->SetIOStream(stream);
114  m_IsConnectionClosed=false;
115  if (!monitor)
116  monitor = new ConnectionMonitorThread(*this, *connection);
117  if (!readThread)
118  readThread = threadManager.newBlockingPeriodicThread(monitor, "Client Connection Reader Thread");
119  connection->sendClientHello();
121  } catch(IOException& e){
122  close();//make sure to clean everything up if we fail to connect
123  }
124  }
125 }
126 
132 }
138  {
139  NTSynchronized sync(LOCK);
140  gotoState(newState);
141  //Disconnect the socket
142  if(connection!=NULL)
143  {
144  connection->close();
145  connection->SetIOStream(NULL); //disconnect the table connection from the IO stream
146  }
147  m_IsConnectionClosed=true;
148  }
149 }
150 
151 
152 
155  sleep_ms(33); //avoid busy wait
156 }
157 
159  if(connectionState!=&ClientConnectionState::DISCONNECTED_FROM_SERVER)//will get io exception when on read thread connection is closed
160  {
161  reconnect();
162  sleep_ms(500);
163  }
164  else
165  {
166  sleep_ms(33); //avoid busy wait
167  }
168 }
169 
170 NetworkTableEntry* ClientConnectionAdapter::GetEntry(EntryId id) {
171  return entryStore.GetEntry(id);
172 }
173 
174 
175 bool ClientConnectionAdapter::keepAlive() {
176  return true;
177 }
178 
179 void ClientConnectionAdapter::clientHello(ProtocolVersion protocolRevision) {
180  throw BadMessageException("A client should not receive a client hello message");
181 }
182 
183 void ClientConnectionAdapter::protocolVersionUnsupported(ProtocolVersion protocolRevision) {
184  close();
185  gotoState(new ClientConnectionState_ProtocolUnsuppotedByServer(protocolRevision));
186 }
187 
188 void ClientConnectionAdapter::serverHelloComplete() {
189  if (connectionState==&ClientConnectionState::CONNECTED_TO_SERVER) {
190  try {
192  entryStore.sendUnknownEntries(*connection);
193  } catch (IOException& e) {
194  ioException(e);
195  }
196  }
197  else
198  throw BadMessageException("A client should only receive a server hello complete once and only after it has connected to the server");
199 }
200 
201 
202 void ClientConnectionAdapter::offerIncomingAssignment(NetworkTableEntry* entry) {
203  entryStore.offerIncomingAssignment(entry);
204 }
205 void ClientConnectionAdapter::offerIncomingUpdate(NetworkTableEntry* entry, SequenceNumber sequenceNumber, EntryValue value) {
206  entryStore.offerIncomingUpdate(entry, sequenceNumber, value);
207 }
208 
209 void ClientConnectionAdapter::offerOutgoingAssignment(NetworkTableEntry* entry) {
210  try {
211  {
212  NTSynchronized sync(LOCK);
213  if(connection!=NULL && connectionState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
214  connection->sendEntryAssignment(*entry);
215  }
216  } catch(IOException& e){
217  ioException(e);
218  }
219 }
220 
221 void ClientConnectionAdapter::offerOutgoingUpdate(NetworkTableEntry* entry) {
222  try {
223  {
224  NTSynchronized sync(LOCK);
225  if(connection!=NULL && connectionState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
226  connection->sendEntryUpdate(*entry);
227  }
228  } catch(IOException& e){
229  ioException(e);
230  }
231 }
232 void ClientConnectionAdapter::flush() {
233  {
234  NTSynchronized sync(LOCK);
235  if(connection!=NULL) {
236  try {
237  connection->flush();
238  } catch (IOException& e) {
239  ioException(e);
240  }
241  }
242  }
243 }
244 void ClientConnectionAdapter::ensureAlive() {
245  {
246  NTSynchronized sync(LOCK);
247  if ((connection!=NULL)&&(!m_IsConnectionClosed)) {
248  try {
249  connection->sendKeepAlive();
250  } catch (IOException& e) {
251  ioException(e);
252  }
253  }
254  else
255  reconnect();//try to reconnect if not connected
256  }
257 }
virtual NTThread * newBlockingPeriodicThread(PeriodicRunnable *r, const char *name)=0
virtual IOStream * createStream()=0
static ClientConnectionState DISCONNECTED_FROM_SERVER
static ClientConnectionState IN_SYNC_WITH_SERVER
virtual void FireConnectedEvent()=0
virtual void stop()=0
ClientConnectionAdapter(ClientNetworkTableEntryStore &entryStore, NTThreadManager &threadManager, IOStreamFactory &streamFactory, ClientConnectionListenerManager &connectionListenerManager, NetworkTableEntryTypeManager &typeManager)
void sendUnknownEntries(NetworkTableConnection &connection)
ClientConnectionState * getConnectionState()
void clearIds()
void badMessage(BadMessageException &e)
static ClientConnectionState CONNECTED_TO_SERVER
virtual void FireDisconnectedEvent()=0
Definition: ITable.h:13

Generated on Sat Apr 26 2014 12:26:45 for WPILibC++ by doxygen 1.8.6