Add ability to set the priority of the socket of the variable server. (#1413)

* Add ability to set the priority of the socket of the variable server.

* Fix build on MacOS.  Apple doesn't have SO_PRIORITY, so set_socket_priority generates an error message.

* Correction to piece of code unrelated to the other commits in this pull request.

---------

Co-authored-by: Stephen Montgomery-Smith <Stephen.J.Montgomery-Smith@nasa.gov>
This commit is contained in:
stephenmontgomerysmith 2023-06-27 09:18:49 -05:00 committed by GitHub
parent e89bf083b2
commit 4db647ed06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 86 additions and 5 deletions

View File

@ -28,6 +28,11 @@ namespace Trick {
unsigned short get_port() ;
void set_port(unsigned short in_port) ;
#ifndef __APPLE__
void set_socket_priority(unsigned short in_socket_priority) ;
void apply_socket_priority(TCDevice *listen_device, TCDevice *device);
#endif
std::string get_user_tag() ;
const std::string& get_user_tag_ref() ;
void set_user_tag(std::string in_tag) ;
@ -75,6 +80,14 @@ namespace Trick {
/** The mutex to stop accepting new connections during restart\n */
pthread_mutex_t restart_pause ; /**< trick_io(**) */
#ifndef __APPLE__
/** Requested variable server socket priority.\n */
unsigned short socket_priority ; /**< trick_units(--) */
/** User requested specific socket priority\n */
bool user_socket_priority_requested ; /**< trick_units(--) */
#endif
} ;
}

View File

@ -48,6 +48,8 @@ PROGRAMMERS:
#define TC_READWRITE_TIMEOUT -2
#define TC_BROKEN_PIPE -3
#define TC_COULD_NOT_SET_SOCKET_PRIORITY 16
/* Set default for blocking timeout limit high */
#define MAX_BLOCKIO_TIMEOUT_LIMIT 1.0e20

View File

@ -111,6 +111,12 @@ int tc_error(TCDevice * device, int on_off);
/* copy a device */
int tc_dev_copy(TCDevice * dest, TCDevice * src);
#ifndef __APPLE__
/* set priority of socket for a device */
#define tc_set_socket_priority(listen_device, device, priority) tc_set_socket_priority_(listen_device, device, priority, __FILE__, __LINE__)
int tc_set_socket_priority_(TCDevice * listen_device, TCDevice * device, int priority, const char *file, int line) ;
#endif
void *trick_bswap_buffer(void *out, void *in, ATTRIBUTES * attr, int tofrom) ;
void *trick_bswap_single_parameter(void *out, void *in, ATTRIBUTES * attr, int tofrom) ;
#ifdef __cplusplus

View File

@ -12,6 +12,7 @@ const char * var_server_get_hostname(void) ;
unsigned short var_server_get_port(void) ;
void var_server_set_port(unsigned short port) ;
void var_server_set_source_address(const char * address) ;
void var_server_set_socket_priority(unsigned short port) ;
const char * var_server_get_user_tag(void) ;
void var_server_set_user_tag(const char * tag) ;

View File

@ -43,6 +43,13 @@ void Trick::VariableServerListenThread::set_port(unsigned short in_port) {
user_port_requested = true ;
}
#ifndef __APPLE__
void Trick::VariableServerListenThread::set_socket_priority(unsigned short in_socket_priority) {
socket_priority = in_socket_priority;
user_socket_priority_requested = true ;
}
#endif
std::string Trick::VariableServerListenThread::get_user_tag() {
return user_tag ;
}
@ -253,3 +260,8 @@ void Trick::VariableServerListenThread::dump( std::ostream & oss ) {
Trick::ThreadBase::dump(oss) ;
}
#ifndef __APPLE__
void Trick::VariableServerListenThread::apply_socket_priority(TCDevice *listen_device, TCDevice *device) {
if (user_socket_priority_requested) tc_set_socket_priority(listen_device, device, socket_priority);
}
#endif

View File

@ -38,6 +38,7 @@ void * Trick::VariableServerThread::thread_body() {
if ( listen_dev->socket_type == SOCK_STREAM ) {
tc_accept(listen_dev, &connection);
tc_blockio(&connection, TC_COMM_ALL_OR_NOTHING);
vs->get_listen_thread().apply_socket_priority(listen_dev, &connection);
}
connection_accepted = true ;

View File

@ -437,6 +437,19 @@ extern "C" void var_server_set_port(unsigned short port) {
the_vs->get_listen_thread().set_port(port);
}
/**
* @relates Trick::VariableServer
* @copydoc Trick::VariableServer::set_socket_priority
* C wrapper Trick::VariableServer::set_socket_priority
*/
extern "C" void var_server_set_socket_priority(unsigned short socket_priority) {
#ifndef __APPLE__
the_vs->get_listen_thread().set_socket_priority(socket_priority);
#else
message_publish(MSG_ERROR,"var_server_set_socket_priority not available on MacOS\n") ;
#endif
}
/**
* @relates Trick::VariableServer
* @copydoc Trick::VariableServer::set_listen_socket

View File

@ -21,6 +21,7 @@ set( TRICKCOMM_SRC
src/tc_read
src/tc_read_byteswap
src/tc_set_blockio
src/tc_set_socket_priority
src/tc_write
src/tc_write_byteswap
src/trick_bswap_buffer

View File

@ -42,11 +42,8 @@ int tc_accept_(TCDevice * listen_device, TCDevice * device, const char *file, in
}
/* Turn off data buffering. This causes data to be sent immediately rather than queing it up until the transmit
buffer is filled. */
setsockopt(the_socket, IPPROTO_TCP, TCP_NODELAY, (const void *) &on, (socklen_t) sizeof(on));
/* Check for error conditon on set socket option */
if (the_socket < 0) {
buffer is filled, and check for error conditon on set socket option */
if (setsockopt(the_socket, IPPROTO_TCP, TCP_NODELAY, (const void *) &on, (socklen_t) sizeof(on)) < 0) {
if (tc_errno == TRICKCOMM_EWOULDBLOCK) {
trick_error_report(listen_device->error_handler,
TRICK_ERROR_ALERT, file,

View File

@ -0,0 +1,35 @@
/*
* Set the priority of a socket.
*/
#ifndef __APPLE__
#ifndef __WIN32__
#include <errno.h>
#include <netinet/tcp.h>
#include <unistd.h>
#endif
#include "trick/tc.h"
#include "trick/tc_proto.h"
#include "trick/trick_byteswap.h"
int tc_set_socket_priority_(TCDevice * listen_device, TCDevice * device, int priority, const char *file, int line)
{
char client_str[TC_TAG_LENGTH + 256];
snprintf(client_str, sizeof(client_str), "(ID = %d tag = %s)", listen_device->client_id, listen_device->client_tag);
if (setsockopt(device->socket, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0) {
trick_error_report(listen_device->error_handler,
TRICK_ERROR_ALERT, file,
line, "tc_set_socket_priority: %s: error on set socket option: " "TC_COULD_NOT_SET_SOCKET_PRIORITY", client_str);
return (TC_COULD_NOT_SET_SOCKET_PRIORITY);
}
return(TC_SUCCESS);
}
#endif