From 4db647ed061d0b5d180dfa470f06d6548c5ef274 Mon Sep 17 00:00:00 2001 From: stephenmontgomerysmith Date: Tue, 27 Jun 2023 09:18:49 -0500 Subject: [PATCH] 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 --- include/trick/VariableServerListenThread.hh | 13 +++++++ include/trick/tc.h | 2 ++ include/trick/tc_proto.h | 6 ++++ include/trick/variable_server_proto.h | 1 + .../VariableServerListenThread.cpp | 12 +++++++ .../VariableServerThread_loop.cpp | 1 + .../VariableServer/var_server_ext.cpp | 13 +++++++ trick_source/trick_utils/comm/CMakeLists.txt | 1 + trick_source/trick_utils/comm/src/tc_accept.c | 7 ++-- .../comm/src/tc_set_socket_priority.c | 35 +++++++++++++++++++ 10 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 trick_source/trick_utils/comm/src/tc_set_socket_priority.c diff --git a/include/trick/VariableServerListenThread.hh b/include/trick/VariableServerListenThread.hh index 4b7af4e6..29242675 100644 --- a/include/trick/VariableServerListenThread.hh +++ b/include/trick/VariableServerListenThread.hh @@ -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 + } ; } diff --git a/include/trick/tc.h b/include/trick/tc.h index 04596c04..c22b8fcb 100644 --- a/include/trick/tc.h +++ b/include/trick/tc.h @@ -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 diff --git a/include/trick/tc_proto.h b/include/trick/tc_proto.h index 0abf0e79..774012bd 100644 --- a/include/trick/tc_proto.h +++ b/include/trick/tc_proto.h @@ -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 diff --git a/include/trick/variable_server_proto.h b/include/trick/variable_server_proto.h index 26eb6698..6048f72f 100644 --- a/include/trick/variable_server_proto.h +++ b/include/trick/variable_server_proto.h @@ -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) ; diff --git a/trick_source/sim_services/VariableServer/VariableServerListenThread.cpp b/trick_source/sim_services/VariableServer/VariableServerListenThread.cpp index 34e4a125..51a0f399 100644 --- a/trick_source/sim_services/VariableServer/VariableServerListenThread.cpp +++ b/trick_source/sim_services/VariableServer/VariableServerListenThread.cpp @@ -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 diff --git a/trick_source/sim_services/VariableServer/VariableServerThread_loop.cpp b/trick_source/sim_services/VariableServer/VariableServerThread_loop.cpp index a5190eed..572af85a 100644 --- a/trick_source/sim_services/VariableServer/VariableServerThread_loop.cpp +++ b/trick_source/sim_services/VariableServer/VariableServerThread_loop.cpp @@ -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 ; diff --git a/trick_source/sim_services/VariableServer/var_server_ext.cpp b/trick_source/sim_services/VariableServer/var_server_ext.cpp index dffa6ad9..9d39e3d2 100644 --- a/trick_source/sim_services/VariableServer/var_server_ext.cpp +++ b/trick_source/sim_services/VariableServer/var_server_ext.cpp @@ -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 diff --git a/trick_source/trick_utils/comm/CMakeLists.txt b/trick_source/trick_utils/comm/CMakeLists.txt index 402f5b4b..7788e067 100644 --- a/trick_source/trick_utils/comm/CMakeLists.txt +++ b/trick_source/trick_utils/comm/CMakeLists.txt @@ -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 diff --git a/trick_source/trick_utils/comm/src/tc_accept.c b/trick_source/trick_utils/comm/src/tc_accept.c index 2d076f27..3fe5bc5e 100644 --- a/trick_source/trick_utils/comm/src/tc_accept.c +++ b/trick_source/trick_utils/comm/src/tc_accept.c @@ -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, diff --git a/trick_source/trick_utils/comm/src/tc_set_socket_priority.c b/trick_source/trick_utils/comm/src/tc_set_socket_priority.c new file mode 100644 index 00000000..5fe4cce8 --- /dev/null +++ b/trick_source/trick_utils/comm/src/tc_set_socket_priority.c @@ -0,0 +1,35 @@ + +/* + * Set the priority of a socket. + */ + +#ifndef __APPLE__ + +#ifndef __WIN32__ +#include +#include +#include +#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