trick/trick_source/sim_services/VariableServer/VariableServerSessionThread.cpp

135 lines
4.2 KiB
C++

#include <iostream>
#include <stdlib.h>
#include "trick/VariableServerSessionThread.hh"
#include "trick/exec_proto.h"
#include "trick/message_proto.h"
#include "trick/message_type.h"
#include "trick/TrickConstant.hh"
#include "trick/UDPConnection.hh"
#include "trick/TCPConnection.hh"
Trick::VariableServer * Trick::VariableServerSessionThread::_vs = NULL ;
static int instance_num = 0;
Trick::VariableServerSessionThread::VariableServerSessionThread() : VariableServerSessionThread (new VariableServerSession()) {}
Trick::VariableServerSessionThread::VariableServerSessionThread(VariableServerSession * session) :
Trick::SysThread(std::string("VarServer" + std::to_string(instance_num++))) , _debug(0), _session(session), _connection(NULL) {
_connection_status = CONNECTION_PENDING ;
pthread_mutex_init(&_connection_status_mutex, NULL);
pthread_cond_init(&_connection_status_cv, NULL);
cancellable = false;
}
Trick::VariableServerSessionThread::~VariableServerSessionThread() {
cleanup();
}
std::ostream& Trick::operator<< (std::ostream& s, Trick::VariableServerSessionThread& vst) {
// Write a JSON representation of a Trick::VariableServerSessionThread to an ostream.
s << " \"connection\":{\n";
s << " \"client_tag\":\"" << vst._connection->getClientTag() << "\",\n";
s << " \"client_IP_address\":\"" << vst._connection->getClientHostname() << "\",\n";
s << " \"client_port\":\"" << vst._connection->getClientPort() << "\",\n";
pthread_mutex_lock(&vst._connection_status_mutex);
if (vst._connection_status == CONNECTION_SUCCESS) {
s << *(vst._session);
}
pthread_mutex_unlock(&vst._connection_status_mutex);
s << " }" << std::endl;
return s;
}
void Trick::VariableServerSessionThread::set_vs_ptr(Trick::VariableServer * in_vs) {
_vs = in_vs ;
}
Trick::VariableServer * Trick::VariableServerSessionThread::get_vs() {
return _vs ;
}
void Trick::VariableServerSessionThread::set_client_tag(std::string tag) {
_connection->setClientTag(tag);
}
void Trick::VariableServerSessionThread::set_connection(Trick::ClientConnection * in_connection) {
_connection = in_connection;
}
Trick::ConnectionStatus Trick::VariableServerSessionThread::wait_for_accept() {
pthread_mutex_lock(&_connection_status_mutex);
while ( _connection_status == CONNECTION_PENDING ) {
pthread_cond_wait(&_connection_status_cv, &_connection_status_mutex);
}
pthread_mutex_unlock(&_connection_status_mutex);
return _connection_status;
}
// Gets called from the main thread as a job
void Trick::VariableServerSessionThread::preload_checkpoint() {
// Stop variable server processing at the top of the processing loop.
force_thread_to_pause();
// Make sure that the _session has been initialized
pthread_mutex_lock(&_connection_status_mutex);
if (_connection_status == CONNECTION_SUCCESS) {
// Let the thread complete any data copying it has to do
// and then suspend data copying until the checkpoint is reloaded.
_session->pause_copy();
// Save the pause state of this thread.
_saved_pause_cmd = _session->get_pause();
// Disallow data writing.
_session->set_pause(true);
// Temporarily "disconnect" the variable references from Trick Managed Memory
// by tagging each as a "bad reference".
_session->disconnect_references();
// Allow data copying to continue.
_session->unpause_copy();
}
pthread_mutex_unlock(&_connection_status_mutex);
}
// Gets called from the main thread as a job
void Trick::VariableServerSessionThread::restart() {
// Set the pause state of this thread back to its "pre-checkpoint reload" state.
_connection->restart();
pthread_mutex_lock(&_connection_status_mutex);
if (_connection_status == CONNECTION_SUCCESS) {
_session->set_pause(_saved_pause_cmd) ;
}
pthread_mutex_unlock(&_connection_status_mutex);
// Restart the variable server processing.
unpause_thread();
}
void Trick::VariableServerSessionThread::cleanup() {
_connection->disconnect();
if (_session != NULL) {
delete _session;
_session = NULL;
}
}