trick/include/trick/VariableServer.hh
jmpenn c4e60d9f9a
Proposed fix for deadlock on shutdown (#1673)
* Proposed fix for deadlock on shutdown

* Terminate C style comment.

* Added needed libs for applicable tests and updated the logic for when allowing/disallowing connections.

* Need to load additional trick libs for applicable tests for Linux.

---------

Co-authored-by: Hong Chen <hong.chen-1@nasa.gov>
2024-03-28 15:15:19 -05:00

390 lines
14 KiB
C++

/*
PURPOSE:
(VariableServer)
*/
#ifndef VARIABLESERVER_HH
#define VARIABLESERVER_HH
#include <map>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <pthread.h>
#include "trick/tc.h"
#include "trick/reference.h"
#include "trick/JobData.hh"
#include "trick/variable_server_sync_types.h"
#include "trick/VariableServerSessionThread.hh"
#include "trick/VariableServerListenThread.hh"
#include "trick/SysThread.hh"
namespace Trick {
/**
This class provides variable server setup.
@author Alex Lin
*/
class VariableServer {
public:
/**
@brief Constructor.
*/
VariableServer() ;
/**
@brief Destructor.
*/
~VariableServer() ;
/**
@brief Write a JSON encoded list of Variable Server Connections to the given stream.
*/
friend std::ostream& operator<< (std::ostream& s, Trick::VariableServer& vs);
/**
@brief Set up the listen port during default_data so it is available at the start of initialization.
*/
int default_data() ;
/**
@brief Start up var_serve_init thread if the variable server is enabled.
*/
int init() ;
/**
@brief Checkpoint restart job
@return always 0
*/
int restart() ;
/**
@brief Sets up freeze call times for scheduled variable server clients.
*/
int freeze_init() ;
void shutdownConnections();
/**
@brief Shutdown the variable server
@return always 0
*/
int shutdown() ;
/**
@brief Gets next time to call copy_data job for a server/client connection in sync mode.
*/
int get_next_sync_call_time() ;
/**
@brief Gets next time to call copy_data job for a server/client connection in freeze mode.
*/
int get_next_freeze_call_time() ;
/**
@brief Copies client variable values at the top of the frame.
*/
int copy_and_write_top() ;
/**
@brief The function to copy client variable values to their output buffers when in sync mode.
*/
int copy_and_write_scheduled() ;
/**
@brief The function to copy client variable values to their output buffers when in sync mode.
*/
int copy_and_write_freeze_scheduled() ;
/**
@brief Copies client variable values at the top of the frame.
*/
int copy_and_write_freeze() ;
/**
@brief Adds a vst to the map.
*/
void add_vst(pthread_t thread_id, VariableServerSessionThread * in_vst ) ;
/**
@brief Adds a vst to the map.
*/
void add_session(pthread_t thread_id, VariableServerSession * in_session ) ;
/**
@brief Get a vst mapped by thread id
@return the VariableServerSessionThread mapped to the thread id if found, or NULL if not found.
*/
Trick::VariableServerSessionThread * get_vst(pthread_t thread_id) ;
/**
@brief Get a session mapped by thread id
@return the VariableServerSession mapped to the thread id if found, or NULL if not found.
*/
Trick::VariableServerSession * get_session(pthread_t thread_id) ;
/**
@brief Delete a vst in the map
*/
void delete_vst(pthread_t thread_id) ;
/**
@brief Delete a session in the map
*/
void delete_session(pthread_t thread_id) ;
/**
@brief @userdesc Return host name from the listen device.
@par Python Usage:
@code <my_string> = trick.var_server_get_hostname() @endcode
*/
const char * get_hostname() ;
/**
@brief Returns the default listen thread.
*/
Trick::VariableServerListenThread & get_listen_thread() ;
/**
@brief @userdesc Enable (default) or disable the variable server.
@par Python Usage:
@code trick.var_server_set_enabled(<on_off>) @endcode
@param on_off - 1 to enable variable server, 0 to disable
@note Disabling the variable server will disable the simulation control panel, TV, MTV, and stripchartting.
@return always 0
*/
void set_enabled(bool on_off) ;
/**
@brief @userdesc Test if the variable server is enabled.
@par Python Usage:
@code <my_bool> = trick.var_server_get_enabled() @endcode
@return 1 if enabled, 0 if disabled
*/
bool get_enabled() ;
/**
@brief @userdesc Test if the variable server info messaging is on.
*/
bool get_info_msg() ;
/**
@brief @userdesc Test if the variable server logging is on.
*/
bool get_log() ;
/**
@brief @userdesc Test if the variable server logging is on.
*/
bool get_session_log() ;
/**
@brief @userdesc Command to turn on variable server info messages (e.g., get a message
when a command is received from any client).
Variable Server info messages will be published using the Trick status message system.
@note If you want to only see info messages for a specific client, you should instead
send "trick.var_debug(1);" from that client.
@par Python Usage:
@code trick.set_var_server_info_msg_on() @endcode
@return always 0
*/
void set_var_server_info_msg_on() ;
/**
@brief @userdesc Command to turn off variable server event info messages (off is the default).
No Variable Server info messages will be published using the Trick status message system.
@par Python Usage:
@code trick.set_var_server_info_msg_off() @endcode
@return always 0
*/
void set_var_server_info_msg_off() ;
/**
@brief @userdesc Command to turn on variable server logging for all clients.
Variable Server log messages will be saved to a varserver_log file in the RUN directory.
@par Python Usage:
@code trick.set_var_server_log_on() @endcode
@return always 0
*/
void set_var_server_log_on() ;
/**
@brief @userdesc Command to turn off variable server logging for all clients.
No Variable Server log messages will be saved to a varserver_log file in the RUN directory.
@par Python Usage:
@code trick.set_var_server_log_off() @endcode
@return always 0
*/
void set_var_server_log_off() ;
/**
@brief @userdesc Command to turn on variable server session logging for all clients.
Each new session will create a file under RUN_<>/session_logs/ containg the client's IP and port and all messages received.
@par Python Usage:
@code trick.set_var_server_log_on() @endcode
@return always 0
*/
void set_var_server_session_log_on() ;
/**
@brief @userdesc Command to turn off variable server session logging for all clients.
No session log will be creeated.
@par Python Usage:
@code trick.set_var_server_log_off() @endcode
@return always 0
*/
void set_var_server_session_log_off() ;
/**
@brief @userdesc Command to open additional variable server listen port.
@param source_address - the name or numeric IP of the machine to bind listen socket. NULL or empty
string will default to default name of machine
@param port - the port.
@par Python Usage:
@code trick.var_server_create_tcp_socket(source_address, port) @endcode
@return 0 if successful
*/
int create_tcp_socket(const char * source_address, unsigned short port ) ;
/**
@brief @userdesc Command to open a udp socket suitable for a single connection
@param source_address - the name or numeric IP of the machine to bind listen socket. NULL or empty
string will default to default name of machine
@param port - the port.
@par Python Usage:
@code trick.var_server_create_udp_socket(source_address, port) @endcode
@return 0 if successful
*/
int create_udp_socket(const char * source_address, unsigned short port ) ;
/**
@brief @userdesc Command to open a multicast socket suitable for a single connection
@param mcast_address - the name or numeric IP of the multicast address to use.
@param source_address - the name or numeric IP of the machine to bind listen socket. NULL or empty
string will default to default name of machine
@param port - the port.
@par Python Usage:
@code trick.var_server_create_multicast_socket(source_address, port) @endcode
@return 0 if successful
*/
int create_multicast_socket( const char * mcast_address,
const char * source_address, unsigned short port ) ;
/**
@brief @userdesc Suspend variable server processing in preparation for checkpoint reload.
@return 0 if successful
*/
int suspendPreCheckpointReload();
/**
@brief @userdesc Resume variable server processing following a checkpoint reload.
@return 0 if successful
*/
int resumePostCheckpointReload();
/**
@brief Called from the S_define to set the copy_data_job ptr.
*/
void set_copy_data_job( Trick::JobData * ) ;
/**
@brief Called from the S_define to set the copy_and_write_freeze_job ptr.
*/
void set_copy_and_write_freeze_job( Trick::JobData * ) ;
protected:
/** Toggle to enable/disable the variable server.\n */
bool enabled ; /**< trick_units(--) */
/** Toggle to turn on/off variable server info messages (e.g., commands received from all clients).\n */
bool info_msg ; /**< trick_units(--) */
/** Toggle to turn on/off variable server logging messages, similar to info_msg except messages only go
to a varserver_log file in the RUN directory.\n */
bool log ; /**< trick_units(--) */
/** Toggle to turn on/off variable server individual session logs. */
bool session_log ; /**< trick_units(--) */
/** Default listen port thread object */
VariableServerListenThread listen_thread ;
/** Pointer to automatic_last job that copies requested variable values to their output buffers in sync mode.\n */
Trick::JobData * copy_data_job ; /**< trick_io(**) trick_units(--) */
/** Pointer to freeze_automatic job that copies requested variable values to their output buffers in sync mode.\n */
Trick::JobData * copy_and_write_freeze_job ; /**< trick_io(**) trick_units(--) */
/** Map thread id to the VariableServerSessionThread object.\n */
std::map < pthread_t , VariableServerSessionThread * > var_server_threads ; /**< trick_io(**) */
std::map < pthread_t , VariableServerSession * > var_server_sessions ; /**< trick_io(**) */
/** Mutex to ensure only one thread manipulates the map of var_server_threads\n */
pthread_mutex_t map_mutex ; /**< trick_io(**) */
/** Map of additional listen threads created by create_tcp_socket.\n */
std::map < pthread_t , VariableServerListenThread * > additional_listen_threads ; /**< trick_io(**) */
} ;
}
Trick::VariableServer * var_server_get_var_server() ;
// external calls to be made available from input processor
int var_add(std::string in_name) ;
int var_add(std::string in_name, std::string units_name) ;
int var_remove(std::string in_name) ;
int var_units(std::string var_name , std::string units_name) ;
int var_exists(std::string in_name) ;
int var_send_once(std::string in_name) ;
int var_send_once(std::string in_name, int numArgs) ;
int var_send() ;
int var_clear() ;
int var_cycle(double in_rate) ;
int var_pause() ;
int var_unpause() ;
int var_exit() ;
int var_write_stdio(int stream , std::string text) ;
int var_set_client_tag( std::string text) ;
int var_debug(int level) ;
int var_ascii() ;
int var_binary() ;
int var_binary_nonames() ;
int var_validate_address(int on_off) ;
int var_set_copy_mode(int mode) ;
int var_set_write_mode(int mode) ;
int var_set_send_stdio(int mode) ;
int var_sync(int mode) ;
int var_set_frame_multiple(unsigned int mult) ;
int var_set_frame_offset(unsigned int offset) ;
int var_set_freeze_frame_multiple(unsigned int mult) ;
int var_set_freeze_frame_offset(unsigned int offset) ;
int var_byteswap(bool on_off) ;
int var_send_list_size() ;
int send_sie_resource() ;
int send_sie_class() ;
int send_sie_enum() ;
int send_sie_top_level_objects() ;
int send_file(std::string file_name) ;
int var_set( const char * var , double value , const char * units = NULL ) ;
int var_set( const char * var , long long value , const char * units = NULL ) ;
int var_set( const char * var , const char * value , const char * units = NULL ) ;
int var_set( const char * var , void * value , const char * units = NULL ) ;
int var_server_log_on() ;
int var_server_log_off() ;
#endif