CMake Changes

This is the changes made by Patrick Plenefisch converting the native
code to use CMake and the CMake Maven Plugin, as opposed to the
native Maven plugin. This is to allow for compatibility with newer
versions of the GCC toolchain. All the cpp sources were moved from
maven style directories to cpp style directories for CMake.

Change-Id: I67f5e3608948f37c83b0990d232105a3784f8593
This commit is contained in:
Brad Miller
2014-03-24 16:13:08 -04:00
parent 33134bef1d
commit 69d9ad70ab
804 changed files with 586 additions and 9377 deletions

View File

@@ -0,0 +1,257 @@
/*
* ClientConnectionAdapter.cpp
*
* Created on: Nov 2, 2012
* Author: Mitchell Wills
*/
#include "networktables2/client/ClientConnectionAdapter.h"
#include "networktables2/util/System.h"
void ClientConnectionAdapter::gotoState(ClientConnectionState* newState){
{
NTSynchronized sync(LOCK);
if(connectionState!=newState){
fprintf(stdout, "[NT] %p entered connection state: %s\n", (void*)this, newState->toString());
fflush(stdout);
if(newState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
connectionListenerManager.FireConnectedEvent();
if(connectionState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
connectionListenerManager.FireDisconnectedEvent();
//TODO find better way to manage memory leak
ClientConnectionState_Error *temp=dynamic_cast<ClientConnectionState_Error *>(connectionState);
connectionState = newState;
if (temp)
delete temp;
}
}
}
/**
* @return the state of the connection
*/
ClientConnectionState* ClientConnectionAdapter::getConnectionState(){
return connectionState;
}
/**
* @return if the client is connected to the server
*/
bool ClientConnectionAdapter::isConnected() {
return getConnectionState()==&ClientConnectionState::IN_SYNC_WITH_SERVER;
}
/**
* Create a new ClientConnectionAdapter
* @param entryStore
* @param threadManager
* @param streamFactory
* @param transactionPool
* @param connectionListenerManager
*/
ClientConnectionAdapter::ClientConnectionAdapter(ClientNetworkTableEntryStore& _entryStore, NTThreadManager& _threadManager, IOStreamFactory& _streamFactory, ClientConnectionListenerManager& _connectionListenerManager, NetworkTableEntryTypeManager& _typeManager):
entryStore(_entryStore),
streamFactory(_streamFactory),
threadManager(_threadManager),
connectionListenerManager(_connectionListenerManager),
typeManager(_typeManager),
readThread(NULL),
monitor(NULL),
connection(NULL){
connectionState = &ClientConnectionState::DISCONNECTED_FROM_SERVER;
}
ClientConnectionAdapter::~ClientConnectionAdapter()
{
if(readThread!=NULL)
readThread->stop();
if (connection)
connection->close();
if(readThread!=NULL)
{
delete readThread;
readThread = NULL;
}
if(monitor!=NULL)
{
delete monitor;
monitor = NULL;
}
close();
if(connection!=NULL){
delete connection;
connection = NULL;
}
//TODO find better way to manage memory leak
ClientConnectionState_Error *temp=dynamic_cast<ClientConnectionState_Error *>(connectionState);
if (temp)
{
delete temp;
connectionState=NULL;
}
}
/*
* Connection management
*/
/**
* Reconnect the client to the server (even if the client is not currently connected)
*/
void ClientConnectionAdapter::reconnect() {
//This is in reconnect so that the entry store doesn't have to be valid when this object is deleted
//Note: clearIds() cannot be in a LOCK critical section
entryStore.clearIds();
{
NTSynchronized sync(LOCK);
close();//close the existing stream and monitor thread if needed
try{
IOStream* stream = streamFactory.createStream();
if(stream==NULL)
return;
if (!connection)
connection = new NetworkTableConnection(stream, typeManager);
else
connection->SetIOStream(stream);
m_IsConnectionClosed=false;
if (!monitor)
monitor = new ConnectionMonitorThread(*this, *connection);
if (!readThread)
readThread = threadManager.newBlockingPeriodicThread(monitor, "Client Connection Reader Thread");
connection->sendClientHello();
gotoState(&ClientConnectionState::CONNECTED_TO_SERVER);
} catch(IOException& e){
close();//make sure to clean everything up if we fail to connect
}
}
}
/**
* Close the client connection
*/
void ClientConnectionAdapter::close() {
close(&ClientConnectionState::DISCONNECTED_FROM_SERVER);
}
/**
* Close the connection to the server and enter the given state
* @param newState
*/
void ClientConnectionAdapter::close(ClientConnectionState* newState) {
{
NTSynchronized sync(LOCK);
gotoState(newState);
//Disconnect the socket
if(connection!=NULL)
{
connection->close();
connection->SetIOStream(NULL); //disconnect the table connection from the IO stream
}
m_IsConnectionClosed=true;
}
}
void ClientConnectionAdapter::badMessage(BadMessageException& e) {
close(new ClientConnectionState_Error(e));
sleep_ms(33); //avoid busy wait
}
void ClientConnectionAdapter::ioException(IOException& e) {
if(connectionState!=&ClientConnectionState::DISCONNECTED_FROM_SERVER)//will get io exception when on read thread connection is closed
{
reconnect();
sleep_ms(500);
}
else
{
sleep_ms(33); //avoid busy wait
}
}
NetworkTableEntry* ClientConnectionAdapter::GetEntry(EntryId id) {
return entryStore.GetEntry(id);
}
bool ClientConnectionAdapter::keepAlive() {
return true;
}
void ClientConnectionAdapter::clientHello(ProtocolVersion protocolRevision) {
throw BadMessageException("A client should not receive a client hello message");
}
void ClientConnectionAdapter::protocolVersionUnsupported(ProtocolVersion protocolRevision) {
close();
gotoState(new ClientConnectionState_ProtocolUnsuppotedByServer(protocolRevision));
}
void ClientConnectionAdapter::serverHelloComplete() {
if (connectionState==&ClientConnectionState::CONNECTED_TO_SERVER) {
try {
gotoState(&ClientConnectionState::IN_SYNC_WITH_SERVER);
entryStore.sendUnknownEntries(*connection);
} catch (IOException& e) {
ioException(e);
}
}
else
throw BadMessageException("A client should only receive a server hello complete once and only after it has connected to the server");
}
void ClientConnectionAdapter::offerIncomingAssignment(NetworkTableEntry* entry) {
entryStore.offerIncomingAssignment(entry);
}
void ClientConnectionAdapter::offerIncomingUpdate(NetworkTableEntry* entry, SequenceNumber sequenceNumber, EntryValue value) {
entryStore.offerIncomingUpdate(entry, sequenceNumber, value);
}
void ClientConnectionAdapter::offerOutgoingAssignment(NetworkTableEntry* entry) {
try {
{
NTSynchronized sync(LOCK);
if(connection!=NULL && connectionState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
connection->sendEntryAssignment(*entry);
}
} catch(IOException& e){
ioException(e);
}
}
void ClientConnectionAdapter::offerOutgoingUpdate(NetworkTableEntry* entry) {
try {
{
NTSynchronized sync(LOCK);
if(connection!=NULL && connectionState==&ClientConnectionState::IN_SYNC_WITH_SERVER)
connection->sendEntryUpdate(*entry);
}
} catch(IOException& e){
ioException(e);
}
}
void ClientConnectionAdapter::flush() {
{
NTSynchronized sync(LOCK);
if(connection!=NULL) {
try {
connection->flush();
} catch (IOException& e) {
ioException(e);
}
}
}
}
void ClientConnectionAdapter::ensureAlive() {
{
NTSynchronized sync(LOCK);
if ((connection!=NULL)&&(!m_IsConnectionClosed)) {
try {
connection->sendKeepAlive();
} catch (IOException& e) {
ioException(e);
}
}
else
reconnect();//try to reconnect if not connected
}
}

View File

@@ -0,0 +1,77 @@
/*
* ClientConnectionState.cpp
*
* Created on: Nov 2, 2012
* Author: Mitchell Wills
*/
#include "networktables2/client/ClientConnectionState.h"
#ifndef _WRS_KERNEL
#include <stdint.h>
#endif
#include <stdlib.h>
#include <memory>
#include <cstring>
/**
* indicates that the client is disconnected from the server
*/
ClientConnectionState ClientConnectionState::DISCONNECTED_FROM_SERVER("DISCONNECTED_FROM_SERVER");
/**
* indicates that the client is connected to the server but has not yet begun communication
*/
ClientConnectionState ClientConnectionState::CONNECTED_TO_SERVER("CONNECTED_TO_SERVER");
/**
* represents that the client has sent the hello to the server and is waiting for a response
*/
ClientConnectionState ClientConnectionState::SENT_HELLO_TO_SERVER("SENT_HELLO_TO_SERVER");
/**
* represents that the client is now in sync with the server
*/
ClientConnectionState ClientConnectionState::IN_SYNC_WITH_SERVER("IN_SYNC_WITH_SERVER");
/**
* Create a new protocol unsupported state
* @param serverVersion
*/
ClientConnectionState_ProtocolUnsuppotedByServer::ClientConnectionState_ProtocolUnsuppotedByServer(ProtocolVersion _serverVersion):
ClientConnectionState("PROTOCOL_UNSUPPORTED_BY_SERVER"),
serverVersion(_serverVersion){}
/**
* @return the protocol version that the server reported it supports
*/
ProtocolVersion ClientConnectionState_ProtocolUnsuppotedByServer::getServerVersion(){
return serverVersion;
}
const char* ClientConnectionState_ProtocolUnsuppotedByServer::toString(){
return "PROTOCOL_UNSUPPORTED_BY_SERVER";
//return "PROTOCOL_UNSUPPORTED_BY_SERVER: Server Version: 0x"+Integer.toHexString(serverVersion);
}
/**
* Create a new error state
* @param e
*/
ClientConnectionState_Error::ClientConnectionState_Error(std::exception& _e):ClientConnectionState("CLIENT_ERROR"),e(_e){
strcpy(msg, "CLIENT_ERROR: ");
strcat(msg, e.what());
}
/**
* @return the exception that caused the client to enter an error state
*/
std::exception& ClientConnectionState_Error::getException(){
return e;
}
const char* ClientConnectionState_Error::toString(){
return msg;
//return "CLIENT_ERROR";
//return "CLIENT_ERROR: "+e.getClass()+": "+e.getMessage();
}
ClientConnectionState::ClientConnectionState(const char* _name){
name = _name;
}
const char* ClientConnectionState::toString(){
return name;
}

View File

@@ -0,0 +1,71 @@
/*
* ClientNetworkTableEntryStore.cpp
*
* Created on: Nov 2, 2012
* Author: Mitchell Wills
*/
#include "networktables2/client/ClientNetworkTableEntryStore.h"
/**
* Create a new ClientNetworkTableEntryStore
* @param transactionPool
* @param listenerManager
*/
ClientNetworkTableEntryStore::ClientNetworkTableEntryStore(TableListenerManager& listenerManager): AbstractNetworkTableEntryStore(listenerManager) {}
ClientNetworkTableEntryStore::~ClientNetworkTableEntryStore(){}
bool ClientNetworkTableEntryStore::addEntry(NetworkTableEntry* newEntry){
{
NTSynchronized sync(LOCK);
NetworkTableEntry* entry = (NetworkTableEntry*)namedEntries[newEntry->name];
if(entry!=NULL){
if(entry->GetId()!=newEntry->GetId()){
idEntries.erase(entry->GetId());
if(newEntry->GetId()!=NetworkTableEntry::UNKNOWN_ID){
entry->SetId(newEntry->GetId());
idEntries[newEntry->GetId()] = entry;
}
}
entry->ForcePut(newEntry->GetSequenceNumber(), newEntry->GetType(), newEntry->GetValue());
}
else{
if(newEntry->GetId()!=NetworkTableEntry::UNKNOWN_ID)
idEntries[newEntry->GetId()] = newEntry;
namedEntries[newEntry->name] = newEntry;
}
}
return true;
}
bool ClientNetworkTableEntryStore::updateEntry(NetworkTableEntry* entry, SequenceNumber sequenceNumber, EntryValue value) {
{
NTSynchronized sync(LOCK);
entry->ForcePut(sequenceNumber, value);
if(entry->GetId()==NetworkTableEntry::UNKNOWN_ID){
return false;
}
return true;
}
}
/**
* Send all unknown entries in the entry store to the given connection
* @param connection
* @throws IOException
*/
void ClientNetworkTableEntryStore::sendUnknownEntries(NetworkTableConnection& connection) {
{
NTSynchronized sync(LOCK);
std::map<std::string, NetworkTableEntry*>::iterator itr;
for(itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
{
NetworkTableEntry* entry = (*itr).second;
if(entry->GetId()==NetworkTableEntry::UNKNOWN_ID)
connection.sendEntryAssignment(*entry);
}
connection.flush();
}
}

View File

@@ -0,0 +1,57 @@
/*
* NetworkTableClient.cpp
*
* Created on: Nov 3, 2012
* Author: Mitchell Wills
*/
#include "networktables2/client/NetworkTableClient.h"
/**
* Create a new NetworkTable Client
* @param streamFactory
* @param threadManager
* @param transactionPool
*/
NetworkTableClient::NetworkTableClient(IOStreamFactory& streamFactory, NetworkTableEntryTypeManager& typeManager, NTThreadManager& threadManager):
NetworkTableNode(*new ClientNetworkTableEntryStore(*this)),
adapter(*new ClientConnectionAdapter((ClientNetworkTableEntryStore&)entryStore, threadManager, streamFactory, *this, typeManager)),
writeManager(*new WriteManager(adapter, threadManager, GetEntryStore(), 1000)),
dirtier(new TransactionDirtier(writeManager)){
GetEntryStore().SetOutgoingReceiver(dirtier);
GetEntryStore().SetIncomingReceiver(&OutgoingEntryReceiver_NULL);
writeManager.start();
}
NetworkTableClient::~NetworkTableClient(){
//Closing this now will cause a reconnect from the write manager -James
//Close();
delete &writeManager;
delete &adapter;
delete &entryStore;
delete dirtier;
}
/**
* force the client to disconnect and reconnect to the server again. Will connect if the client is currently disconnected
*/
void NetworkTableClient::reconnect() {
adapter.reconnect();
}
void NetworkTableClient::Close() {
adapter.close();
}
void NetworkTableClient::stop() {
writeManager.stop();
Close();
}
bool NetworkTableClient::IsConnected() {
return adapter.isConnected();
}
bool NetworkTableClient::IsServer() {
return false;
}