#include #include #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; } }