MIDAS
Loading...
Searching...
No Matches
RPC Functions (rpc_xxx)

Classes

class  RPC_CLIENT_CONNECTION
 
struct  TR_FIFO
 
struct  TLS_POINTER
 
class  RPE
 

Macros

#define RPC_CM_SET_CLIENT_INFO   11000
 
#define RPC_CM_SET_WATCHDOG_PARAMS   11001
 
#define RPC_CM_CLEANUP   11002
 
#define RPC_CM_GET_WATCHDOG_INFO   11003
 
#define RPC_CM_MSG_LOG   11004
 
#define RPC_CM_EXECUTE   11005
 
#define RPC_CM_SYNCHRONIZE   11006
 
#define RPC_CM_ASCTIME   11007
 
#define RPC_CM_TIME   11008
 
#define RPC_CM_MSG   11009
 
#define RPC_CM_EXIST   11011
 
#define RPC_CM_MSG_RETRIEVE   11012
 
#define RPC_CM_MSG_LOG1   11013
 
#define RPC_CM_CHECK_CLIENT   11014
 
#define RPC_BM_OPEN_BUFFER   11100
 
#define RPC_BM_CLOSE_BUFFER   11101
 
#define RPC_BM_CLOSE_ALL_BUFFERS   11102
 
#define RPC_BM_GET_BUFFER_INFO   11103
 
#define RPC_BM_GET_BUFFER_LEVEL   11104
 
#define RPC_BM_INIT_BUFFER_COUNTERS   11105
 
#define RPC_BM_SET_CACHE_SIZE   11106
 
#define RPC_BM_ADD_EVENT_REQUEST   11107
 
#define RPC_BM_REMOVE_EVENT_REQUEST   11108
 
#define RPC_BM_SEND_EVENT   11109
 
#define RPC_BM_FLUSH_CACHE   11110
 
#define RPC_BM_RECEIVE_EVENT   11111
 
#define RPC_BM_MARK_READ_WAITING   11112
 
#define RPC_BM_EMPTY_BUFFERS   11113
 
#define RPC_BM_SKIP_EVENT   11114
 
#define RPC_BM_RECEIVE_EVENT_CXX   11115
 
#define RPC_DB_OPEN_DATABASE   11200
 
#define RPC_DB_CLOSE_DATABASE   11201
 
#define RPC_DB_CLOSE_ALL_DATABASES   11202
 
#define RPC_DB_CREATE_KEY   11203
 
#define RPC_DB_CREATE_LINK   11204
 
#define RPC_DB_SET_VALUE   11205
 
#define RPC_DB_GET_VALUE   11206
 
#define RPC_DB_FIND_KEY   11207
 
#define RPC_DB_FIND_LINK   11208
 
#define RPC_DB_GET_PATH   11209
 
#define RPC_DB_DELETE_KEY   11210
 
#define RPC_DB_ENUM_KEY   11211
 
#define RPC_DB_GET_KEY   11212
 
#define RPC_DB_GET_DATA   11213
 
#define RPC_DB_SET_DATA   11214
 
#define RPC_DB_SET_DATA_INDEX   11215
 
#define RPC_DB_SET_MODE   11216
 
#define RPC_DB_GET_RECORD_SIZE   11219
 
#define RPC_DB_GET_RECORD   11220
 
#define RPC_DB_SET_RECORD   11221
 
#define RPC_DB_ADD_OPEN_RECORD   11222
 
#define RPC_DB_REMOVE_OPEN_RECORD   11223
 
#define RPC_DB_SAVE   11224
 
#define RPC_DB_LOAD   11225
 
#define RPC_DB_SET_CLIENT_NAME   11226
 
#define RPC_DB_RENAME_KEY   11227
 
#define RPC_DB_ENUM_LINK   11228
 
#define RPC_DB_REORDER_KEY   11229
 
#define RPC_DB_CREATE_RECORD   11230
 
#define RPC_DB_GET_DATA_INDEX   11231
 
#define RPC_DB_GET_KEY_TIME   11232
 
#define RPC_DB_GET_OPEN_RECORDS   11233
 
#define RPC_DB_FLUSH_DATABASE   11235
 
#define RPC_DB_SET_DATA_INDEX1   11236
 
#define RPC_DB_GET_KEY_INFO   11237
 
#define RPC_DB_GET_DATA1   11238
 
#define RPC_DB_SET_NUM_VALUES   11239
 
#define RPC_DB_CHECK_RECORD   11240
 
#define RPC_DB_GET_NEXT_LINK   11241
 
#define RPC_DB_GET_LINK   11242
 
#define RPC_DB_GET_LINK_DATA   11243
 
#define RPC_DB_SET_LINK_DATA   11244
 
#define RPC_DB_SET_LINK_DATA_INDEX   11245
 
#define RPC_DB_SET_DATA1   11246
 
#define RPC_DB_NOTIFY_CLIENTS_ARRAY   11247
 
#define RPC_DB_GET_PARENT   11248
 
#define RPC_DB_COPY_XML   11249
 
#define RPC_EL_SUBMIT   11400
 
#define RPC_AL_CHECK   11500
 
#define RPC_AL_TRIGGER_ALARM   11501
 
#define RPC_RC_TRANSITION   12000
 
#define RPC_ANA_CLEAR_HISTOS   13000
 
#define RPC_LOG_REWIND   14000
 
#define RPC_TEST   15000
 
#define RPC_TEST2   15001
 
#define RPC_TEST2_CXX   15002
 
#define RPC_TEST3_CXX   15003
 
#define RPC_TEST4_CXX   15004
 
#define RPC_CNAF16   16000
 
#define RPC_CNAF24   16001
 
#define RPC_MANUAL_TRIG   17000
 
#define RPC_JRPC   18000
 
#define RPC_BRPC   18001
 
#define RPC_JRPC_CXX   18002
 
#define RPC_BRPC_CXX   18003
 
#define RPC_ID_WATCHDOG   99997
 
#define RPC_ID_SHUTDOWN   99998
 
#define RPC_ID_EXIT   99999
 

Functions

RPC_SERVER_ACCEPTIONrpc_get_mserver_acception ()
 
static RPC_SERVER_ACCEPTIONrpc_new_server_acception ()
 
void rpc_calc_convert_flags (INT hw_type, INT remote_hw_type, INT *convert_flags)
 
void rpc_get_convert_flags (INT *convert_flags)
 
void rpc_ieee2vax_float (float *var)
 
void rpc_vax2ieee_float (float *var)
 
void rpc_vax2ieee_double (double *var)
 
void rpc_ieee2vax_double (double *var)
 
void rpc_convert_single (void *data, INT tid, INT flags, INT convert_flags)
 
void rpc_convert_data (void *data, INT tid, INT flags, INT total_size, INT convert_flags)
 
INT rpc_tid_size (INT id)
 
const char * rpc_tid_name (INT id)
 
const char * rpc_tid_name_old (INT id)
 
int rpc_name_tid (const char *name)
 
INT rpc_register_client (const char *name, RPC_LIST *list)
 
INT rpc_register_functions (const RPC_LIST *new_list, RPC_HANDLER func)
 
INT rpc_deregister_functions ()
 
INT rpc_register_function (INT id, INT(*func)(INT, void **))
 
static int handle_msg_odb (int n, const NET_COMMAND *nc)
 
INT rpc_client_dispatch (int sock)
 
INT rpc_client_connect (const char *host_name, INT port, const char *client_name, HNDLE *hConnection)
 
void rpc_client_check ()
 
INT rpc_server_connect (const char *host_name, const char *exp_name)
 
static RPC_CLIENT_CONNECTIONrpc_get_locked_client_connection (HNDLE hConn)
 
INT rpc_client_disconnect (HNDLE hConn, BOOL bShutdown)
 
INT rpc_server_disconnect ()
 
bool rpc_is_remote (void)
 
bool rpc_is_connected (void)
 
std::string rpc_get_mserver_hostname (void)
 
bool rpc_is_mserver (void)
 
INT rpc_get_hw_type ()
 
INT rpc_get_timeout (HNDLE hConn)
 
INT rpc_set_timeout (HNDLE hConn, int timeout_msec, int *old_timeout_msec)
 
INT rpc_get_convert_flags (void)
 
const char * rpc_get_mserver_path ()
 
INT rpc_set_mserver_path (const char *path)
 
std::string rpc_get_name ()
 
INT rpc_set_name (const char *name)
 
INT rpc_set_debug (void(*func)(const char *), INT mode)
 
void rpc_debug_printf (const char *format,...)
 
void rpc_va_arg (va_list *arg_ptr, INT arg_type, void *arg)
 
static void rpc_call_encode (va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
 
static int rpc_call_decode (va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
 
static void rpc_call_encode_cxx (va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
 
static int rpc_call_decode_cxx (va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
 
static int rpc_find_rpc (int routine_id, RPC_LIST *pentry, bool *prpc_cxx)
 
INT rpc_client_call (HNDLE hConn, DWORD routine_id,...)
 
INT rpc_call (DWORD routine_id,...)
 
INT rpc_set_opt_tcp_size (INT tcp_size)
 
INT rpc_get_opt_tcp_size ()
 
INT rpc_send_event (INT buffer_handle, const EVENT_HEADER *pevent, int unused, INT async_flag, INT mode)
 
INT rpc_send_event1 (INT buffer_handle, const EVENT_HEADER *pevent)
 
INT rpc_send_event_sg (INT buffer_handle, int sg_n, const char *const sg_ptr[], const size_t sg_len[])
 
INT rpc_flush_event ()
 
static INT rpc_transition_dispatch (INT idx, void *prpc_param[])
 
int cm_query_transition (int *transition, int *run_number, int *trans_time)
 
static int recv_net_command_realloc (RPC_SERVER_ACCEPTION *sa, char **pbuf, int *pbufsize, INT *remaining)
 
INT recv_tcp_check (int sock)
 
static int recv_event_server_realloc (INT idx, RPC_SERVER_ACCEPTION *psa, char **pbuffer, int *pbuffer_size)
 
INT rpc_register_server (int port, int *plsock, int *pport)
 
INT rpc_register_listener (int port, RPC_HANDLER func, int *plsock, int *pport)
 
static INT rpc_execute_old (INT sock, int xroutine_id, const RPC_LIST &rl, char *buffer, INT convert_flags)
 
static INT rpc_execute_cxx (INT sock, int xroutine_id, const RPC_LIST &rl, char *buffer, INT convert_flags)
 
int rpc_test_rpc_test2 ()
 
int rpc_test_rpc_test2_cxx ()
 
int rpc_test_rpc_test3_cxx ()
 
int rpc_test_rpc_test4_cxx ()
 
int rpc_test_rpc ()
 
static std::atomic_bool gAllowedHostsEnabled (false)
 
INT rpc_clear_allowed_hosts ()
 
INT rpc_add_allowed_host (const char *hostname)
 
INT rpc_check_allowed_host (const char *hostname)
 
static INT rpc_socket_check_allowed_host (int sock)
 
INT rpc_server_accept (int lsock)
 
INT rpc_client_accept (int lsock)
 
INT rpc_server_callback (struct callback_addr *pcallback)
 
INT rpc_server_loop (void)
 
INT rpc_server_receive_rpc (RPC_SERVER_ACCEPTION *sa)
 
INT rpc_server_receive_event (int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
 
int rpc_flush_event_socket (int timeout_msec)
 
INT rpc_server_shutdown (void)
 
INT rpc_check_channels (void)
 
void rpc_server_acception_struct::close ()
 

Variables

static std::mutex _client_connections_mutex
 
static std::vector< RPC_CLIENT_CONNECTION * > _client_connections
 
static RPC_SERVER_CONNECTION _server_connection
 
static bool _rpc_is_remote = false
 
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
 
static RPC_SERVER_ACCEPTION_mserver_acception = NULL
 
static std::vector< RPC_LISTrpc_list
 
static std::mutex rpc_list_mutex
 
static int _opt_tcp_size = OPT_TCP_SIZE
 
static std::string _mserver_path
 
static std::mutex _tr_fifo_mutex
 
static TR_FIFO _tr_fifo [10]
 
static int _tr_fifo_wp = 0
 
static int _tr_fifo_rp = 0
 
static TLS_POINTERtls_buffer = NULL
 
static int tls_size = 0
 
static std::vector< std::string > gAllowedHosts
 
static std::mutex gAllowedHostsMutex
 

Detailed Description

dox dox dox


Macro Definition Documentation

◆ RPC_AL_CHECK

#define RPC_AL_CHECK   11500

Definition at line 114 of file mrpc.h.

◆ RPC_AL_TRIGGER_ALARM

#define RPC_AL_TRIGGER_ALARM   11501

Definition at line 115 of file mrpc.h.

◆ RPC_ANA_CLEAR_HISTOS

#define RPC_ANA_CLEAR_HISTOS   13000

Definition at line 119 of file mrpc.h.

◆ RPC_BM_ADD_EVENT_REQUEST

#define RPC_BM_ADD_EVENT_REQUEST   11107

Definition at line 43 of file mrpc.h.

◆ RPC_BM_CLOSE_ALL_BUFFERS

#define RPC_BM_CLOSE_ALL_BUFFERS   11102

Definition at line 38 of file mrpc.h.

◆ RPC_BM_CLOSE_BUFFER

#define RPC_BM_CLOSE_BUFFER   11101

Definition at line 37 of file mrpc.h.

◆ RPC_BM_EMPTY_BUFFERS

#define RPC_BM_EMPTY_BUFFERS   11113

Definition at line 49 of file mrpc.h.

◆ RPC_BM_FLUSH_CACHE

#define RPC_BM_FLUSH_CACHE   11110

Definition at line 46 of file mrpc.h.

◆ RPC_BM_GET_BUFFER_INFO

#define RPC_BM_GET_BUFFER_INFO   11103

Definition at line 39 of file mrpc.h.

◆ RPC_BM_GET_BUFFER_LEVEL

#define RPC_BM_GET_BUFFER_LEVEL   11104

Definition at line 40 of file mrpc.h.

◆ RPC_BM_INIT_BUFFER_COUNTERS

#define RPC_BM_INIT_BUFFER_COUNTERS   11105

Definition at line 41 of file mrpc.h.

◆ RPC_BM_MARK_READ_WAITING

#define RPC_BM_MARK_READ_WAITING   11112

Definition at line 48 of file mrpc.h.

◆ RPC_BM_OPEN_BUFFER

#define RPC_BM_OPEN_BUFFER   11100

Definition at line 36 of file mrpc.h.

◆ RPC_BM_RECEIVE_EVENT

#define RPC_BM_RECEIVE_EVENT   11111

Definition at line 47 of file mrpc.h.

◆ RPC_BM_RECEIVE_EVENT_CXX

#define RPC_BM_RECEIVE_EVENT_CXX   11115

Definition at line 51 of file mrpc.h.

◆ RPC_BM_REMOVE_EVENT_REQUEST

#define RPC_BM_REMOVE_EVENT_REQUEST   11108

Definition at line 44 of file mrpc.h.

◆ RPC_BM_SEND_EVENT

#define RPC_BM_SEND_EVENT   11109

Definition at line 45 of file mrpc.h.

◆ RPC_BM_SET_CACHE_SIZE

#define RPC_BM_SET_CACHE_SIZE   11106

Definition at line 42 of file mrpc.h.

◆ RPC_BM_SKIP_EVENT

#define RPC_BM_SKIP_EVENT   11114

Definition at line 50 of file mrpc.h.

◆ RPC_BRPC

#define RPC_BRPC   18001

Definition at line 135 of file mrpc.h.

◆ RPC_BRPC_CXX

#define RPC_BRPC_CXX   18003

Definition at line 137 of file mrpc.h.

◆ RPC_CM_ASCTIME

#define RPC_CM_ASCTIME   11007

Definition at line 28 of file mrpc.h.

◆ RPC_CM_CHECK_CLIENT

#define RPC_CM_CHECK_CLIENT   11014

Definition at line 34 of file mrpc.h.

◆ RPC_CM_CLEANUP

#define RPC_CM_CLEANUP   11002

Definition at line 23 of file mrpc.h.

◆ RPC_CM_EXECUTE

#define RPC_CM_EXECUTE   11005

Definition at line 26 of file mrpc.h.

◆ RPC_CM_EXIST

#define RPC_CM_EXIST   11011

Definition at line 31 of file mrpc.h.

◆ RPC_CM_GET_WATCHDOG_INFO

#define RPC_CM_GET_WATCHDOG_INFO   11003

Definition at line 24 of file mrpc.h.

◆ RPC_CM_MSG

#define RPC_CM_MSG   11009

Definition at line 30 of file mrpc.h.

◆ RPC_CM_MSG_LOG

#define RPC_CM_MSG_LOG   11004

Definition at line 25 of file mrpc.h.

◆ RPC_CM_MSG_LOG1

#define RPC_CM_MSG_LOG1   11013

Definition at line 33 of file mrpc.h.

◆ RPC_CM_MSG_RETRIEVE

#define RPC_CM_MSG_RETRIEVE   11012

Definition at line 32 of file mrpc.h.

◆ RPC_CM_SET_CLIENT_INFO

#define RPC_CM_SET_CLIENT_INFO   11000

routine IDs for RPC calls

Definition at line 21 of file mrpc.h.

◆ RPC_CM_SET_WATCHDOG_PARAMS

#define RPC_CM_SET_WATCHDOG_PARAMS   11001

Definition at line 22 of file mrpc.h.

◆ RPC_CM_SYNCHRONIZE

#define RPC_CM_SYNCHRONIZE   11006

Definition at line 27 of file mrpc.h.

◆ RPC_CM_TIME

#define RPC_CM_TIME   11008

Definition at line 29 of file mrpc.h.

◆ RPC_CNAF16

#define RPC_CNAF16   16000

Definition at line 129 of file mrpc.h.

◆ RPC_CNAF24

#define RPC_CNAF24   16001

Definition at line 130 of file mrpc.h.

◆ RPC_DB_ADD_OPEN_RECORD

#define RPC_DB_ADD_OPEN_RECORD   11222

Definition at line 73 of file mrpc.h.

◆ RPC_DB_CHECK_RECORD

#define RPC_DB_CHECK_RECORD   11240

Definition at line 90 of file mrpc.h.

◆ RPC_DB_CLOSE_ALL_DATABASES

#define RPC_DB_CLOSE_ALL_DATABASES   11202

Definition at line 55 of file mrpc.h.

◆ RPC_DB_CLOSE_DATABASE

#define RPC_DB_CLOSE_DATABASE   11201

Definition at line 54 of file mrpc.h.

◆ RPC_DB_COPY_XML

#define RPC_DB_COPY_XML   11249

Definition at line 99 of file mrpc.h.

◆ RPC_DB_CREATE_KEY

#define RPC_DB_CREATE_KEY   11203

Definition at line 56 of file mrpc.h.

◆ RPC_DB_CREATE_LINK

#define RPC_DB_CREATE_LINK   11204

Definition at line 57 of file mrpc.h.

◆ RPC_DB_CREATE_RECORD

#define RPC_DB_CREATE_RECORD   11230

Definition at line 81 of file mrpc.h.

◆ RPC_DB_DELETE_KEY

#define RPC_DB_DELETE_KEY   11210

Definition at line 63 of file mrpc.h.

◆ RPC_DB_ENUM_KEY

#define RPC_DB_ENUM_KEY   11211

Definition at line 64 of file mrpc.h.

◆ RPC_DB_ENUM_LINK

#define RPC_DB_ENUM_LINK   11228

Definition at line 79 of file mrpc.h.

◆ RPC_DB_FIND_KEY

#define RPC_DB_FIND_KEY   11207

Definition at line 60 of file mrpc.h.

◆ RPC_DB_FIND_LINK

#define RPC_DB_FIND_LINK   11208

Definition at line 61 of file mrpc.h.

◆ RPC_DB_FLUSH_DATABASE

#define RPC_DB_FLUSH_DATABASE   11235

Definition at line 85 of file mrpc.h.

◆ RPC_DB_GET_DATA

#define RPC_DB_GET_DATA   11213

Definition at line 66 of file mrpc.h.

◆ RPC_DB_GET_DATA1

#define RPC_DB_GET_DATA1   11238

Definition at line 88 of file mrpc.h.

◆ RPC_DB_GET_DATA_INDEX

#define RPC_DB_GET_DATA_INDEX   11231

Definition at line 82 of file mrpc.h.

◆ RPC_DB_GET_KEY

#define RPC_DB_GET_KEY   11212

Definition at line 65 of file mrpc.h.

◆ RPC_DB_GET_KEY_INFO

#define RPC_DB_GET_KEY_INFO   11237

Definition at line 87 of file mrpc.h.

◆ RPC_DB_GET_KEY_TIME

#define RPC_DB_GET_KEY_TIME   11232

Definition at line 83 of file mrpc.h.

◆ RPC_DB_GET_LINK

#define RPC_DB_GET_LINK   11242

Definition at line 92 of file mrpc.h.

◆ RPC_DB_GET_LINK_DATA

#define RPC_DB_GET_LINK_DATA   11243

Definition at line 93 of file mrpc.h.

◆ RPC_DB_GET_NEXT_LINK

#define RPC_DB_GET_NEXT_LINK   11241

Definition at line 91 of file mrpc.h.

◆ RPC_DB_GET_OPEN_RECORDS

#define RPC_DB_GET_OPEN_RECORDS   11233

Definition at line 84 of file mrpc.h.

◆ RPC_DB_GET_PARENT

#define RPC_DB_GET_PARENT   11248

Definition at line 98 of file mrpc.h.

◆ RPC_DB_GET_PATH

#define RPC_DB_GET_PATH   11209

Definition at line 62 of file mrpc.h.

◆ RPC_DB_GET_RECORD

#define RPC_DB_GET_RECORD   11220

Definition at line 71 of file mrpc.h.

◆ RPC_DB_GET_RECORD_SIZE

#define RPC_DB_GET_RECORD_SIZE   11219

Definition at line 70 of file mrpc.h.

◆ RPC_DB_GET_VALUE

#define RPC_DB_GET_VALUE   11206

Definition at line 59 of file mrpc.h.

◆ RPC_DB_LOAD

#define RPC_DB_LOAD   11225

Definition at line 76 of file mrpc.h.

◆ RPC_DB_NOTIFY_CLIENTS_ARRAY

#define RPC_DB_NOTIFY_CLIENTS_ARRAY   11247

Definition at line 97 of file mrpc.h.

◆ RPC_DB_OPEN_DATABASE

#define RPC_DB_OPEN_DATABASE   11200

Definition at line 53 of file mrpc.h.

◆ RPC_DB_REMOVE_OPEN_RECORD

#define RPC_DB_REMOVE_OPEN_RECORD   11223

Definition at line 74 of file mrpc.h.

◆ RPC_DB_RENAME_KEY

#define RPC_DB_RENAME_KEY   11227

Definition at line 78 of file mrpc.h.

◆ RPC_DB_REORDER_KEY

#define RPC_DB_REORDER_KEY   11229

Definition at line 80 of file mrpc.h.

◆ RPC_DB_SAVE

#define RPC_DB_SAVE   11224

Definition at line 75 of file mrpc.h.

◆ RPC_DB_SET_CLIENT_NAME

#define RPC_DB_SET_CLIENT_NAME   11226

Definition at line 77 of file mrpc.h.

◆ RPC_DB_SET_DATA

#define RPC_DB_SET_DATA   11214

Definition at line 67 of file mrpc.h.

◆ RPC_DB_SET_DATA1

#define RPC_DB_SET_DATA1   11246

Definition at line 96 of file mrpc.h.

◆ RPC_DB_SET_DATA_INDEX

#define RPC_DB_SET_DATA_INDEX   11215

Definition at line 68 of file mrpc.h.

◆ RPC_DB_SET_DATA_INDEX1

#define RPC_DB_SET_DATA_INDEX1   11236

Definition at line 86 of file mrpc.h.

◆ RPC_DB_SET_LINK_DATA

#define RPC_DB_SET_LINK_DATA   11244

Definition at line 94 of file mrpc.h.

◆ RPC_DB_SET_LINK_DATA_INDEX

#define RPC_DB_SET_LINK_DATA_INDEX   11245

Definition at line 95 of file mrpc.h.

◆ RPC_DB_SET_MODE

#define RPC_DB_SET_MODE   11216

Definition at line 69 of file mrpc.h.

◆ RPC_DB_SET_NUM_VALUES

#define RPC_DB_SET_NUM_VALUES   11239

Definition at line 89 of file mrpc.h.

◆ RPC_DB_SET_RECORD

#define RPC_DB_SET_RECORD   11221

Definition at line 72 of file mrpc.h.

◆ RPC_DB_SET_VALUE

#define RPC_DB_SET_VALUE   11205

Definition at line 58 of file mrpc.h.

◆ RPC_EL_SUBMIT

#define RPC_EL_SUBMIT   11400

Definition at line 112 of file mrpc.h.

◆ RPC_ID_EXIT

#define RPC_ID_EXIT   99999

Definition at line 141 of file mrpc.h.

◆ RPC_ID_SHUTDOWN

#define RPC_ID_SHUTDOWN   99998

Definition at line 140 of file mrpc.h.

◆ RPC_ID_WATCHDOG

#define RPC_ID_WATCHDOG   99997

Definition at line 139 of file mrpc.h.

◆ RPC_JRPC

#define RPC_JRPC   18000

Definition at line 134 of file mrpc.h.

◆ RPC_JRPC_CXX

#define RPC_JRPC_CXX   18002

Definition at line 136 of file mrpc.h.

◆ RPC_LOG_REWIND

#define RPC_LOG_REWIND   14000

Definition at line 121 of file mrpc.h.

◆ RPC_MANUAL_TRIG

#define RPC_MANUAL_TRIG   17000

Definition at line 132 of file mrpc.h.

◆ RPC_RC_TRANSITION

#define RPC_RC_TRANSITION   12000

Definition at line 117 of file mrpc.h.

◆ RPC_TEST

#define RPC_TEST   15000

Definition at line 123 of file mrpc.h.

◆ RPC_TEST2

#define RPC_TEST2   15001

Definition at line 124 of file mrpc.h.

◆ RPC_TEST2_CXX

#define RPC_TEST2_CXX   15002

Definition at line 125 of file mrpc.h.

◆ RPC_TEST3_CXX

#define RPC_TEST3_CXX   15003

Definition at line 126 of file mrpc.h.

◆ RPC_TEST4_CXX

#define RPC_TEST4_CXX   15004

Definition at line 127 of file mrpc.h.

Function Documentation

◆ close()

void RPC_SERVER_ACCEPTION::close ( )

Definition at line 11776 of file midas.cxx.

11777{
11778 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11779
11780 if (is_mserver) {
11781 assert(_mserver_acception == this);
11782 _mserver_acception = NULL;
11783 is_mserver = false;
11784 }
11785
11786 /* close server connection */
11787 if (recv_sock)
11789 if (send_sock)
11791 if (event_sock)
11793
11794 /* free TCP cache */
11795 if (net_buffer) {
11796 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11797 free(net_buffer);
11798 net_buffer = NULL;
11799 net_buffer_size = 0;
11800 }
11801
11802 /* mark this entry as invalid */
11803 clear();
11804}
INT ss_socket_close(int *sockp)
Definition system.cxx:5310
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11744
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cm_query_transition()

int cm_query_transition ( int *  transition,
int *  run_number,
int *  trans_time 
)

Definition at line 14670 of file midas.cxx.

14694{
14695 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14696
14697 if (_tr_fifo_wp == _tr_fifo_rp)
14698 return FALSE;
14699
14700 if (transition)
14702
14703 if (run_number)
14705
14706 if (trans_time)
14707 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14708
14709 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14710
14711 // implicit unlock
14712 return TRUE;
14713}
#define FALSE
Definition cfortran.h:309
INT transition(INT run_number, char *error)
Definition consume.cxx:35
static int _tr_fifo_rp
Definition midas.cxx:14604
static int _tr_fifo_wp
Definition midas.cxx:14603
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14602
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14601
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14595
int run_number
Definition midas.cxx:14596
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gAllowedHostsEnabled()

static std::atomic_bool gAllowedHostsEnabled ( false  )
static
Here is the caller graph for this function:

◆ handle_msg_odb()

static int handle_msg_odb ( int  n,
const NET_COMMAND nc 
)
static

Definition at line 12164 of file midas.cxx.

12164 {
12165 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
12166 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
12167 /* update a changed record */
12168 HNDLE hDB = *((INT *) nc->param);
12169 HNDLE hKeyRoot = *((INT *) nc->param + 1);
12170 HNDLE hKey = *((INT *) nc->param + 2);
12171 int index = *((INT *) nc->param + 3);
12172 return db_update_record_local(hDB, hKeyRoot, hKey, index);
12173 }
12174 return CM_VERSION_MISMATCH;
12175}
#define CM_VERSION_MISMATCH
Definition midas.h:587
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition odb.cxx:14145
HNDLE hKey
DWORD n[4]
Definition mana.cxx:247
INT index
Definition mana.cxx:271
HNDLE hDB
main ODB handle
Definition mana.cxx:207
INT HNDLE
Definition midas.h:132
int INT
Definition midas.h:129
char param[32]
Definition msystem.h:294
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_event_server_realloc()

static int recv_event_server_realloc ( INT  idx,
RPC_SERVER_ACCEPTION psa,
char **  pbuffer,
int *  pbuffer_size 
)
static

Definition at line 14935 of file midas.cxx.

14957{
14958 int sock = psa->event_sock;
14959
14960 //printf("recv_event_server: idx %d, buffer %p, buffer_size %d\n", idx, buffer, buffer_size);
14961
14962 const size_t header_size = (sizeof(EVENT_HEADER) + sizeof(INT));
14963
14964 char header_buf[header_size];
14965
14966 // First read the header.
14967 //
14968 // Data format is:
14969 // INT buffer handle (4 bytes)
14970 // EVENT_HEADER (16 bytes)
14971 // event data
14972 // ALIGN8() padding
14973 // ...next event
14974
14975 int hrd = recv_tcp2(sock, header_buf, header_size, 1);
14976
14977 if (hrd == 0) {
14978 // timeout waiting for data
14979 return 0;
14980 }
14981
14982 /* abort if connection broken */
14983 if (hrd < 0) {
14984 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d", hrd);
14985 return -1;
14986 }
14987
14988 if (hrd < (int) header_size) {
14989 int hrd1 = recv_tcp2(sock, header_buf + hrd, header_size - hrd, 0);
14990
14991 /* abort if connection broken */
14992 if (hrd1 <= 0) {
14993 cm_msg(MERROR, "recv_event_server", "recv_tcp2(more header) returned %d", hrd1);
14994 return -1;
14995 }
14996
14997 hrd += hrd1;
14998 }
14999
15000 /* abort if connection broken */
15001 if (hrd != (int) header_size) {
15002 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d instead of %d", hrd, (int) header_size);
15003 return -1;
15004 }
15005
15006 INT *pbh = (INT *) header_buf;
15007 EVENT_HEADER *pevent = (EVENT_HEADER *) (((INT *) header_buf) + 1);
15008
15009 /* convert header little endian/big endian */
15010 if (psa->convert_flags) {
15017 }
15018
15019 int event_size = pevent->data_size + sizeof(EVENT_HEADER);
15020 int total_size = ALIGN8(event_size);
15021
15022 //printf("recv_event_server: buffer_handle %d, event_id 0x%04x, serial 0x%08x, data_size %d, event_size %d, total_size %d\n", *pbh, pevent->event_id, pevent->serial_number, pevent->data_size, event_size, total_size);
15023
15024 if (pevent->data_size == 0) {
15025 for (int i=0; i<5; i++) {
15026 printf("recv_event_server: header[%d]: 0x%08x\n", i, pbh[i]);
15027 }
15028 abort();
15029 }
15030
15031 /* check for sane event size */
15032 if (event_size <= 0 || total_size <= 0) {
15033 cm_msg(MERROR, "recv_event_server",
15034 "received event header with invalid data_size %d: event_size %d, total_size %d", pevent->data_size,
15035 event_size, total_size);
15036 return -1;
15037 }
15038
15039 //printf("recv_event_server: idx %d, bh %d, event header: id %d, mask %d, serial %d, data_size %d, event_size %d, total_size %d\n", idx, *pbh, pevent->event_id, pevent->trigger_mask, pevent->serial_number, pevent->data_size, event_size, total_size);
15040
15041
15042 int bufsize = sizeof(INT) + total_size;
15043
15044 // Second, check that output buffer is big enough
15045
15046 /* check if data part fits in buffer */
15047 if (*pbuffer_size < bufsize) {
15048 int newsize = 1024 + ALIGN8(bufsize);
15049
15050 //printf("recv_event_server: buffer realloc %d -> %d\n", *pbuffer_size, newsize);
15051
15052 char *newbuf = (char *) realloc(*pbuffer, newsize);
15053 if (newbuf == NULL) {
15054 cm_msg(MERROR, "recv_event_server", "cannot realloc() event buffer from %d to %d bytes", *pbuffer_size,
15055 newsize);
15056 return -1;
15057 }
15058 *pbuffer = newbuf;
15059 *pbuffer_size = newsize;
15060 }
15061
15062 // Third, copy header into output buffer
15063
15064 memcpy(*pbuffer, header_buf, header_size);
15065
15066 // Forth, read the event data
15067
15068 int to_read = sizeof(INT) + total_size - header_size;
15069 int rptr = header_size;
15070
15071 if (to_read > 0) {
15072 int drd = recv_tcp2(sock, (*pbuffer) + rptr, to_read, 0);
15073
15074 /* abort if connection broken */
15075 if (drd <= 0) {
15076 cm_msg(MERROR, "recv_event_server", "recv_tcp2(data) returned %d instead of %d", drd, to_read);
15077 return -1;
15078 }
15079 }
15080
15081 return bufsize;
15082}
#define TID_INT32
Definition midas.h:339
#define MERROR
Definition midas.h:559
#define TID_UINT32
Definition midas.h:337
#define TID_INT16
Definition midas.h:335
#define ALIGN8(x)
Definition midas.h:522
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition system.cxx:5641
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:939
void rpc_convert_single(void *data, INT tid, INT flags, INT convert_flags)
Definition midas.cxx:11914
INT i
Definition mdump.cxx:32
int event_size
Definition msysmon.cxx:527
short int event_id
Definition midas.h:853
DWORD data_size
Definition midas.h:857
DWORD serial_number
Definition midas.h:855
DWORD time_stamp
Definition midas.h:856
short int trigger_mask
Definition midas.h:854
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_net_command_realloc()

static int recv_net_command_realloc ( RPC_SERVER_ACCEPTION sa,
char **  pbuf,
int *  pbufsize,
INT remaining 
)
static

Definition at line 14747 of file midas.cxx.

14775{
14776 char *buffer = NULL; // buffer is changed to point to *pbuf when we receive the NET_COMMAND header
14777
14778 int sock = sa->recv_sock;
14779
14780 if (!sa->net_buffer) {
14781 if (sa->is_mserver)
14783 else
14785
14786 sa->net_buffer = (char *) malloc(sa->net_buffer_size);
14787 //printf("sa %p idx %d, net_buffer %p+%d\n", sa, idx, sa->net_buffer, sa->net_buffer_size);
14788 sa->write_ptr = 0;
14789 sa->read_ptr = 0;
14790 sa->misalign = 0;
14791 }
14792 if (!sa->net_buffer) {
14793 cm_msg(MERROR, "recv_net_command_realloc", "Cannot allocate %d bytes for network buffer", sa->net_buffer_size);
14794 return -1;
14795 }
14796
14797 int copied = 0;
14798 int param_size = -1;
14799
14800 int write_ptr = sa->write_ptr;
14801 int read_ptr = sa->read_ptr;
14802 int misalign = sa->misalign;
14803 char *net_buffer = sa->net_buffer;
14804
14805 do {
14806 if (write_ptr - read_ptr >= (INT) sizeof(NET_COMMAND_HEADER) - copied) {
14807 if (param_size == -1) {
14808 if (copied > 0) {
14809 /* assemble split header */
14810 memcpy(buffer + copied, net_buffer + read_ptr, (INT) sizeof(NET_COMMAND_HEADER) - copied);
14811 NET_COMMAND *nc = (NET_COMMAND *) (buffer);
14812 param_size = (INT) nc->header.param_size;
14813 } else {
14814 NET_COMMAND *nc = (NET_COMMAND *) (net_buffer + read_ptr);
14815 param_size = (INT) nc->header.param_size;
14816 }
14817
14818 if (sa->convert_flags)
14819 rpc_convert_single(&param_size, TID_UINT32, 0, sa->convert_flags);
14820 }
14821
14822 //printf("recv_net_command_realloc: param_size %d, NET_COMMAND_HEADER %d, buffer_size %d\n", param_size, (int)sizeof(NET_COMMAND_HEADER), *pbufsize);
14823
14824 /* check if parameters fit in buffer */
14825 if (*pbufsize < (param_size + (int) sizeof(NET_COMMAND_HEADER))) {
14826 int new_size = param_size + sizeof(NET_COMMAND_HEADER) + 1024;
14827 char *p = (char *) realloc(*pbuf, new_size);
14828 //printf("recv_net_command_realloc: reallocate buffer %d -> %d, %p\n", *pbufsize, new_size, p);
14829 if (p == NULL) {
14830 cm_msg(MERROR, "recv_net_command_realloc", "cannot reallocate buffer from %d bytes to %d bytes", *pbufsize, new_size);
14831 sa->read_ptr = 0;
14832 sa->write_ptr = 0;
14833 return -1;
14834 }
14835 *pbuf = p;
14836 *pbufsize = new_size;
14837 }
14838
14839 buffer = *pbuf;
14840
14841 /* check if we have all parameters in buffer */
14842 if (write_ptr - read_ptr >= param_size + (INT) sizeof(NET_COMMAND_HEADER) - copied)
14843 break;
14844 }
14845
14846 /* not enough data, so copy partially and get new */
14847 int size = write_ptr - read_ptr;
14848
14849 if (size > 0) {
14850 memcpy(buffer + copied, net_buffer + read_ptr, size);
14851 copied += size;
14852 read_ptr = write_ptr;
14853 }
14854#ifdef OS_UNIX
14855 do {
14856 write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14857
14858 /* don't return if an alarm signal was cought */
14859 } while (write_ptr == -1 && errno == EINTR);
14860#else
14861 write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14862#endif
14863
14864 /* abort if connection broken */
14865 if (write_ptr <= 0) {
14866 if (write_ptr == 0)
14867 cm_msg(MERROR, "recv_net_command_realloc", "rpc connection from \'%s\' on \'%s\' unexpectedly closed", sa->prog_name.c_str(), sa->host_name.c_str());
14868 else
14869 cm_msg(MERROR, "recv_net_command_realloc", "recv() returned %d, errno: %d (%s)", write_ptr, errno, strerror(errno));
14870
14871 if (remaining)
14872 *remaining = 0;
14873
14874 return write_ptr;
14875 }
14876
14877 read_ptr = misalign;
14878 write_ptr += misalign;
14879
14880 misalign = write_ptr % 8;
14881 } while (TRUE);
14882
14883 /* copy rest of parameters */
14884 int size = param_size + sizeof(NET_COMMAND_HEADER) - copied;
14885 memcpy(buffer + copied, net_buffer + read_ptr, size);
14886 read_ptr += size;
14887
14888 if (remaining) {
14889 /* don't keep rpc_server_receive in an infinite loop */
14890 if (write_ptr - read_ptr < param_size)
14891 *remaining = 0;
14892 else
14893 *remaining = write_ptr - read_ptr;
14894 }
14895
14896 sa->write_ptr = write_ptr;
14897 sa->read_ptr = read_ptr;
14898 sa->misalign = misalign;
14899
14900 return size + copied;
14901}
#define NET_BUFFER_SIZE
Definition msystem.h:114
#define NET_TCP_SIZE
Definition midas.h:266
NET_COMMAND_HEADER header
Definition msystem.h:293
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_tcp_check()

INT recv_tcp_check ( int  sock)

Definition at line 14905 of file midas.cxx.

14923{
14924 /* figure out to which connection socket belongs */
14925 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14926 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14927 return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14928 }
14929
14930 return 0;
14931}
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition midas.cxx:11743
Here is the caller graph for this function:

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char *  hostname)

Definition at line 16707 of file midas.cxx.

16724{
16725 //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
16726
16727 gAllowedHostsMutex.lock();
16728 gAllowedHosts.push_back(hostname);
16729 gAllowedHostsEnabled = true;
16730 gAllowedHostsMutex.unlock();
16731
16732 return RPC_SUCCESS;
16733}
#define RPC_SUCCESS
Definition midas.h:699
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition midas.cxx:16679
static std::vector< std::string > gAllowedHosts
Definition midas.cxx:16678
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_calc_convert_flags()

void rpc_calc_convert_flags ( INT  hw_type,
INT  remote_hw_type,
INT convert_flags 
)
  • ASCII format *‍/

Definition at line 11816 of file midas.cxx.

11816 {
11817 *convert_flags = 0;
11818
11819 /* big/little endian conversion */
11820 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11821 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11822 && (hw_type & DRI_BIG_ENDIAN)))
11823 *convert_flags |= CF_ENDIAN;
11824
11825 /* float conversion between IEEE and VAX G */
11826 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11827 *convert_flags |= CF_VAX2IEEE;
11828
11829 /* float conversion between VAX G and IEEE */
11830 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11831 *convert_flags |= CF_IEEE2VAX;
11832
11834 //if (remote_hw_type & DR_ASCII)
11835 // *convert_flags |= CF_ASCII;
11836}
#define DRI_LITTLE_ENDIAN
Definition msystem.h:48
#define DRF_G_FLOAT
Definition msystem.h:51
#define DRI_BIG_ENDIAN
Definition msystem.h:49
#define DRF_IEEE
Definition msystem.h:50
#define CF_ENDIAN
Definition midas.h:1547
#define CF_IEEE2VAX
Definition midas.h:1548
#define CF_VAX2IEEE
Definition midas.h:1549
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 14217 of file midas.cxx.

14241{
14242 va_list ap;
14243 INT i, status;
14244
14245 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
14246 routine_id &= ~RPC_NO_REPLY;
14247
14248 //if (rpc_no_reply)
14249 // printf("rpc_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
14250
14251 int send_sock = _server_connection.send_sock;
14252 int rpc_timeout = _server_connection.rpc_timeout;
14253
14254 if (!send_sock) {
14255 fprintf(stderr, "rpc_call(routine_id=%d) failed, no connection to mserver.\n", routine_id);
14256 return RPC_NET_ERROR;
14257 }
14258
14259 if (!_mutex_rpc) {
14260 /* create a local mutex for multi-threaded applications */
14262 }
14263
14264 status = ss_mutex_wait_for(_mutex_rpc, 10000 + rpc_timeout);
14265 if (status != SS_SUCCESS) {
14266 cm_msg(MERROR, "rpc_call", "Mutex timeout");
14267 return RPC_MUTEX_TIMEOUT;
14268 }
14269
14270 /* find rpc definition */
14271
14272 RPC_LIST rpc_entry;
14273 bool rpc_cxx = false;
14274
14275 status = rpc_find_rpc(routine_id, &rpc_entry, &rpc_cxx);
14276
14277 if (status != RPC_SUCCESS) {
14279 cm_msg(MERROR, "rpc_call", "invalid rpc ID (%d)", routine_id);
14280 return RPC_INVALID_ID;
14281 }
14282
14283 const char* rpc_name = rpc_entry.name;
14284
14285 /* prepare output buffer */
14286
14287 NET_COMMAND* nc = NULL;
14288
14289 /* examine variable argument list and convert it to parameter array */
14290 va_start(ap, routine_id);
14291
14292 if (rpc_cxx)
14293 rpc_call_encode_cxx(ap, rpc_entry, &nc);
14294 else
14295 rpc_call_encode(ap, rpc_entry, &nc);
14296
14297 va_end(ap);
14298
14299 nc->header.routine_id = routine_id;
14300
14301 if (rpc_no_reply)
14303
14304 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
14305
14306 /* do not wait for reply if requested RPC_NO_REPLY */
14307 if (rpc_no_reply) {
14308 i = send_tcp(send_sock, (char *) nc, send_size, 0);
14309
14310 if (i != send_size) {
14312 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
14313 free(nc);
14314 return RPC_NET_ERROR;
14315 }
14316
14318 free(nc);
14319 return RPC_SUCCESS;
14320 }
14321
14322 /* in TCP mode, send and wait for reply on send socket */
14323 i = send_tcp(send_sock, (char *) nc, send_size, 0);
14324 if (i != send_size) {
14326 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
14327 free(nc);
14328 return RPC_NET_ERROR;
14329 }
14330
14331 free(nc);
14332 nc = NULL;
14333
14334 bool restore_watchdog_timeout = false;
14335 BOOL watchdog_call;
14336 DWORD watchdog_timeout;
14337 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
14338
14339 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, rpc_timeout);
14340
14341 if (!rpc_is_remote()) {
14342 // if RPC is remote, we are connected to an mserver,
14343 // the mserver takes care of watchdog timeouts.
14344 // otherwise we should make sure the watchdog timeout
14345 // is longer than the RPC timeout. K.O.
14346 if (rpc_timeout >= (int) watchdog_timeout) {
14347 restore_watchdog_timeout = true;
14348 cm_set_watchdog_params_local(watchdog_call, rpc_timeout + 1000);
14349 }
14350 }
14351
14352 DWORD rpc_status = 0;
14353 DWORD buf_size = 0;
14354 char* buf = NULL;
14355
14356 status = ss_recv_net_command(send_sock, &rpc_status, &buf_size, &buf, rpc_timeout);
14357
14358 if (restore_watchdog_timeout) {
14359 cm_set_watchdog_params_local(watchdog_call, watchdog_timeout);
14360 }
14361
14362 /* drop the mutex, we are done with the socket, argument unpacking is done from our own buffer */
14363
14365
14366 /* check for reply errors */
14367
14368 if (status == SS_TIMEOUT) {
14369 cm_msg(MERROR, "rpc_call", "routine \"%s\": timeout waiting for reply, program abort", rpc_name);
14370 if (buf)
14371 free(buf);
14372 abort(); // cannot continue - our mserver is not talking to us!
14373 return RPC_TIMEOUT;
14374 }
14375
14376 if (status != SS_SUCCESS) {
14377 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, ss_recv_net_command() status %d, program abort", rpc_name, status);
14378 if (buf)
14379 free(buf);
14380 abort(); // cannot continue - something is wrong with our mserver connection
14381 return RPC_NET_ERROR;
14382 }
14383
14384 if (rpc_status == RPC_INVALID_ID) {
14385 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, unknown RPC, status %d", rpc_name, rpc_status);
14386 if (buf)
14387 free(buf);
14388 return rpc_status;
14389 }
14390
14391 /* extract result variables and place it to argument list */
14392
14393 va_start(ap, routine_id);
14394
14395 if (rpc_cxx)
14396 status = rpc_call_decode_cxx(ap, rpc_entry, buf, buf_size);
14397 else
14398 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
14399
14400 if (status != RPC_SUCCESS) {
14401 rpc_status = status;
14402 }
14403
14404 va_end(ap);
14405
14406 if (buf)
14407 free(buf);
14408
14409 return rpc_status;
14410}
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3397
INT cm_set_watchdog_params_local(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3316
#define SS_SUCCESS
Definition midas.h:664
#define SS_TIMEOUT
Definition midas.h:675
#define RPC_INVALID_ID
Definition midas.h:707
#define RPC_MUTEX_TIMEOUT
Definition midas.h:711
#define RPC_TIMEOUT
Definition midas.h:703
#define RPC_NET_ERROR
Definition midas.h:702
unsigned int DWORD
Definition mcstd.h:51
#define RPC_NO_REPLY
Definition midas.h:396
INT ss_mutex_release(MUTEX_T *mutex)
Definition system.cxx:3236
INT ss_mutex_create(MUTEX_T **mutex, BOOL recursive)
Definition system.cxx:3020
INT ss_recv_net_command(int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
Definition system.cxx:5714
INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5364
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3116
bool rpc_is_remote(void)
Definition midas.cxx:12994
static void rpc_call_encode(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13464
static void rpc_call_encode_cxx(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13709
static int rpc_find_rpc(int routine_id, RPC_LIST *pentry, bool *prpc_cxx)
Definition midas.cxx:14002
static int rpc_call_decode(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13637
static RPC_SERVER_CONNECTION _server_connection
Definition midas.cxx:11739
static int rpc_call_decode_cxx(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13909
static MUTEX_T * _mutex_rpc
Definition midas.cxx:227
DWORD BOOL
Definition midas.h:105
DWORD status
Definition odbhist.cxx:39
const char * name
Definition midas.h:1535
Here is the call graph for this function:

◆ rpc_call_decode()

static int rpc_call_decode ( va_list &  ap,
const RPC_LIST rl,
const char *  buf,
size_t  buf_size 
)
static

Definition at line 13637 of file midas.cxx.

13638{
13639 //printf("rpc_call_decode!\n");
13640
13641 bool debug = false;
13642
13643 if (debug)
13644 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13645
13646 /* extract result variables and place it to argument list */
13647
13648 const char* param_ptr = buf;
13649
13650 for (int i = 0; rl.param[i].tid != 0; i++) {
13651 int tid = rl.param[i].tid;
13652 int flags = rl.param[i].flags;
13653 int arg_type = 0;
13654
13655 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13656 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13657 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13658
13659 if (bpointer)
13660 arg_type = TID_ARRAY;
13661 else
13662 arg_type = rl.param[i].tid;
13663
13664 if (tid == TID_FLOAT && !bpointer)
13665 arg_type = TID_DOUBLE;
13666
13667 char arg[8];
13668 rpc_va_arg(&ap, arg_type, arg);
13669
13670 if (rl.param[i].flags & RPC_OUT) {
13671
13672 if (param_ptr == NULL) {
13673 cm_msg(MERROR, "rpc_call_decode", "routine \"%s\": no data in RPC reply, needed to decode an RPC_OUT parameter. param_ptr is NULL", rl.name);
13674 return RPC_NET_ERROR;
13675 }
13676
13677 tid = rl.param[i].tid;
13678 int arg_size = rpc_tid_size(tid);
13679
13680 if (tid == TID_STRING || tid == TID_LINK)
13681 arg_size = strlen((char *) (param_ptr)) + 1;
13682
13683 if (flags & RPC_VARARRAY) {
13684 arg_size = *((INT *) param_ptr);
13685 param_ptr += ALIGN8(sizeof(INT));
13686 }
13687
13688 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13689 arg_size = rl.param[i].n;
13690
13691 /* parameter size is always aligned */
13692 int param_size = ALIGN8(arg_size);
13693
13694 /* return parameters are always pointers */
13695 if (*((char **) arg)) {
13696 if (debug)
13697 printf("decode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, memcpy %d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13698 memcpy((void *) *((char **) arg), param_ptr, arg_size);
13699 }
13700
13701 param_ptr += param_size;
13702 }
13703 }
13704
13705 return RPC_SUCCESS;
13706}
#define TID_DOUBLE
Definition midas.h:343
#define TID_STRUCT
Definition midas.h:348
#define TID_LINK
Definition midas.h:350
#define TID_STRING
Definition midas.h:346
#define TID_ARRAY
Definition midas.h:347
#define TID_FLOAT
Definition midas.h:341
void rpc_va_arg(va_list *arg_ptr, INT arg_type, void *arg)
Definition midas.cxx:13426
INT rpc_tid_size(INT id)
Definition midas.cxx:11990
BOOL debug
debug printouts
Definition mana.cxx:254
#define RPC_OUT
Definition midas.h:1516
#define RPC_POINTER
Definition midas.h:1517
#define RPC_VARARRAY
Definition midas.h:1519
#define RPC_FIXARRAY
Definition midas.h:1518
RPC_PARAM param[MAX_RPC_PARAMS]
Definition midas.h:1536
INT id
Definition midas.h:1534
WORD flags
Definition midas.h:1527
WORD tid
Definition midas.h:1526
INT n
Definition midas.h:1528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_call_decode_cxx()

static int rpc_call_decode_cxx ( va_list &  ap,
const RPC_LIST rl,
const char *  buf,
size_t  buf_size 
)
static

Definition at line 13909 of file midas.cxx.

13910{
13911 //printf("rpc_call_decode_cxx!\n");
13912
13913 bool debug = false;
13914
13915 //if (rl.id == RPC_TEST2)
13916 // debug = true;
13917
13918 //if (rl.id == RPC_TEST2_CXX)
13919 // debug = true;
13920
13921 if (debug)
13922 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13923
13924 /* extract result variables and place it to argument list */
13925
13926 const char* param_ptr = buf;
13927
13928 for (int i = 0; rl.param[i].tid != 0; i++) {
13929 const int tid = rl.param[i].tid;
13930 const int flags = rl.param[i].flags;
13931 int arg_type = 0;
13932
13933 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13934 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13935 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13936
13937 if (bpointer)
13938 arg_type = TID_ARRAY;
13939 else
13940 arg_type = tid;
13941
13942 if (tid == TID_FLOAT && !bpointer)
13943 arg_type = TID_DOUBLE;
13944
13945 char arg[sizeof(double)+sizeof(uint64_t)+sizeof(char*)];
13946 rpc_va_arg(&ap, arg_type, arg);
13947
13948 if (flags & RPC_OUT) {
13949
13950 if (param_ptr == NULL) {
13951 cm_msg(MERROR, "rpc_call_decode_cxx", "routine \"%s\": no data in RPC reply, needed to decode an RPC_OUT parameter. param_ptr is NULL", rl.name);
13952 return RPC_NET_ERROR;
13953 }
13954
13955 int arg_size = rpc_tid_size(tid);
13956
13957 if (tid == TID_STRING || tid == TID_LINK) {
13958 arg_size = strlen((char *) (param_ptr)) + 1;
13959
13960 if (debug)
13961 printf("decode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, string [%s]\n", i, flags, tid, arg_type, arg_size, (char *) (param_ptr));
13962 }
13963
13964 if (flags & RPC_VARARRAY) {
13965 arg_size = *((INT *) param_ptr);
13966 param_ptr += ALIGN8(sizeof(INT));
13967 }
13968
13969 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13970 arg_size = rl.param[i].n;
13971
13972 /* parameter size is always aligned */
13973 int param_size = ALIGN8(arg_size);
13974
13975 /* return parameters are always pointers */
13976 void* parg = *(char**) arg;
13977 if (parg) {
13978 if ((tid == TID_STRING) && (flags & RPC_CXX)) {
13979 if (debug)
13980 printf("decode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, param_size %3d, assign %3d to std::string at %p, offset %zu, string [%s]\n", i, flags, tid, arg_type, arg_size, param_size, arg_size, parg, param_ptr - buf, param_ptr);
13981 *(std::string*)parg = param_ptr;
13982 } else if ((tid == TID_ARRAY) && (flags & RPC_CXX)) {
13983 if (debug)
13984 printf("decode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, param_size %3d, assign %3d to std::vector at %p, offset %zu\n", i, flags, tid, arg_type, arg_size, param_size, arg_size, parg, param_ptr - buf);
13985 std::vector<char>* pvec = (std::vector<char>*)parg;
13986 pvec->clear();
13987 pvec->insert(pvec->end(), param_ptr, param_ptr + arg_size);
13988 } else {
13989 if (debug)
13990 printf("decode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, param_size %3d, memcpy %3d to %p, offset %zu\n", i, flags, tid, arg_type, arg_size, param_size, arg_size, parg, param_ptr - buf);
13991 memcpy(parg, param_ptr, arg_size);
13992 }
13993 }
13994
13995 param_ptr += param_size;
13996 }
13997 }
13998
13999 return RPC_SUCCESS;
14000}
#define RPC_CXX
Definition midas.h:1521
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_call_encode()

static void rpc_call_encode ( va_list &  ap,
const RPC_LIST rl,
NET_COMMAND **  nc 
)
static

Definition at line 13464 of file midas.cxx.

13465{
13466 //printf("rpc_call_encode!\n");
13467
13468 bool debug = false;
13469
13470 if (debug) {
13471 printf("encode rpc_id %d \"%s\"\n", rl.id, rl.name);
13472 for (int i=0; rl.param[i].tid != 0; i++) {
13473 int tid = rl.param[i].tid;
13474 int flags = rl.param[i].flags;
13475 int n = rl.param[i].n;
13476 printf("i=%d, tid %d, flags 0x%x, n %d\n", i, tid, flags, n);
13477 }
13478 }
13479
13480 char args[MAX_RPC_PARAMS][8];
13481
13482 for (int i=0; rl.param[i].tid != 0; i++) {
13483 int tid = rl.param[i].tid;
13484 int flags = rl.param[i].flags;
13485 int arg_type = 0;
13486
13487 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13488 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13489 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13490
13491 if (bpointer)
13492 arg_type = TID_ARRAY;
13493 else
13494 arg_type = tid;
13495
13496 /* floats are passed as doubles, at least under NT */
13497 if (tid == TID_FLOAT && !bpointer)
13498 arg_type = TID_DOUBLE;
13499
13500 //printf("arg %d, tid %d, flags 0x%x, arg_type %d, bpointer %d\n", i, tid, flags, arg_type, bpointer);
13501
13502 rpc_va_arg(&ap, arg_type, args[i]);
13503 }
13504
13505 size_t buf_size = sizeof(NET_COMMAND) + 4 * 1024;
13506 char* buf = (char *)malloc(buf_size);
13507 assert(buf);
13508
13509 (*nc) = (NET_COMMAND*) buf;
13510
13511 /* find out if we are on a big endian system */
13512 bool bbig = ((rpc_get_hw_type() & DRI_BIG_ENDIAN) > 0);
13513
13514 char* param_ptr = (*nc)->param;
13515
13516 for (int i=0; rl.param[i].tid != 0; i++) {
13517 int tid = rl.param[i].tid;
13518 int flags = rl.param[i].flags;
13519 int arg_type = 0;
13520
13521 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13522 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13523 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13524
13525 if (bpointer)
13526 arg_type = TID_ARRAY;
13527 else
13528 arg_type = tid;
13529
13530 /* floats are passed as doubles, at least under NT */
13531 if (tid == TID_FLOAT && !bpointer)
13532 arg_type = TID_DOUBLE;
13533
13534 /* get pointer to argument */
13535 //char arg[8];
13536 //rpc_va_arg(&ap, arg_type, arg);
13537
13538 char* arg = args[i];
13539
13540 /* shift 1- and 2-byte parameters to the LSB on big endian systems */
13541 if (bbig) {
13542 if (tid == TID_UINT8 || tid == TID_CHAR || tid == TID_INT8) {
13543 arg[0] = arg[3];
13544 }
13545 if (tid == TID_UINT16 || tid == TID_INT16) {
13546 arg[0] = arg[2];
13547 arg[1] = arg[3];
13548 }
13549 }
13550
13551 if (flags & RPC_IN) {
13552 int arg_size = 0;
13553
13554 if (bpointer)
13555 arg_size = rpc_tid_size(tid);
13556 else
13557 arg_size = rpc_tid_size(arg_type);
13558
13559 /* for strings, the argument size depends on the string length */
13560 if (tid == TID_STRING || tid == TID_LINK) {
13561 arg_size = 1 + strlen((char *) *((char **) arg));
13562 }
13563
13564 /* for varibale length arrays, the size is given by
13565 the next parameter on the stack */
13566 if (flags & RPC_VARARRAY) {
13567 //va_list aptmp;
13569 //va_copy(aptmp, ap);
13570
13571 //char arg_tmp[8];
13572 //rpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
13573
13574 const char* arg_tmp = args[i+1];
13575
13576 /* for (RPC_IN+RPC_OUT) parameters, size argument is a pointer */
13577 if (flags & RPC_OUT)
13578 arg_size = *((INT *) *((void **) arg_tmp));
13579 else
13580 arg_size = *((INT *) arg_tmp);
13581
13582 *((INT *) param_ptr) = ALIGN8(arg_size);
13583 param_ptr += ALIGN8(sizeof(INT));
13584
13585 //va_end(aptmp);
13586 }
13587
13588 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13589 arg_size = rl.param[i].n;
13590
13591 /* always align parameter size */
13592 int param_size = ALIGN8(arg_size);
13593
13594 {
13595 size_t param_offset = (char *) param_ptr - (char *)(*nc);
13596
13597 if (param_offset + param_size + 16 > buf_size) {
13598 size_t new_size = param_offset + param_size + 1024;
13599 //printf("resize nc %zu to %zu\n", buf_size, new_size);
13600 buf = (char *) realloc(buf, new_size);
13601 assert(buf);
13602 buf_size = new_size;
13603 (*nc) = (NET_COMMAND*) buf;
13604 param_ptr = buf + param_offset;
13605 }
13606 }
13607
13608 if (bpointer) {
13609 if (debug) {
13610 printf("encode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, memcpy pointer %d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13611 }
13612 memcpy(param_ptr, (void *) *((void **) arg), arg_size);
13613 } else if (tid == TID_FLOAT) {
13614 if (debug) {
13615 printf("encode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, double->float\n", i, flags, tid, arg_type, arg_size, param_size);
13616 }
13617 /* floats are passed as doubles on most systems */
13618 *((float *) param_ptr) = (float) *((double *) arg);
13619 } else {
13620 if (debug) {
13621 printf("encode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, memcpy %d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13622 }
13623 memcpy(param_ptr, arg, arg_size);
13624 }
13625
13626 param_ptr += param_size;
13627 }
13628 }
13629
13630 (*nc)->header.param_size = (POINTER_T) param_ptr - (POINTER_T) (*nc)->param;
13631
13632 if (debug)
13633 printf("encode rpc_id %d \"%s\" buf_size %d, param_size %d\n", rl.id, rl.name, (int)buf_size, (*nc)->header.param_size);
13634}
#define TID_UINT8
Definition midas.h:328
#define TID_INT8
Definition midas.h:330
#define TID_CHAR
Definition midas.h:331
#define TID_UINT16
Definition midas.h:333
INT rpc_get_hw_type()
Definition midas.cxx:13067
#define RPC_IN
Definition midas.h:1515
#define MAX_RPC_PARAMS
Definition midas.h:1531
#define POINTER_T
Definition midas.h:166
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_call_encode_cxx()

static void rpc_call_encode_cxx ( va_list &  ap,
const RPC_LIST rl,
NET_COMMAND **  nc 
)
static

Definition at line 13709 of file midas.cxx.

13710{
13711 //printf("rpc_call_encode_cxx!\n");
13712
13713 bool debug = false;
13714
13715 //if (rl.id == RPC_TEST2)
13716 // debug = true;
13717
13718 //if (rl.id == RPC_TEST2_CXX)
13719 // debug = true;
13720
13721 if (debug) {
13722 printf("encode rpc_id %d \"%s\"\n", rl.id, rl.name);
13723 for (int i=0; rl.param[i].tid != 0; i++) {
13724 int tid = rl.param[i].tid;
13725 int flags = rl.param[i].flags;
13726 int n = rl.param[i].n;
13727 printf("param %2d, tid %2d, flags 0x%02x, n %3d\n", i, tid, flags, n);
13728 }
13729 }
13730
13731 char args[MAX_RPC_PARAMS][sizeof(char*)];
13732
13733 for (int i=0; rl.param[i].tid != 0; i++) {
13734 int tid = rl.param[i].tid;
13735 int flags = rl.param[i].flags;
13736 int arg_type = 0;
13737
13738 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13739 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13740 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13741
13742 if (bpointer)
13743 arg_type = TID_ARRAY;
13744 else
13745 arg_type = tid;
13746
13747 /* floats are passed as doubles, at least under NT */
13748 if (tid == TID_FLOAT && !bpointer)
13749 arg_type = TID_DOUBLE;
13750
13751 //printf("arg %d, tid %d, flags 0x%x, arg_type %d, bpointer %d\n", i, tid, flags, arg_type, bpointer);
13752
13753 rpc_va_arg(&ap, arg_type, args[i]);
13754 }
13755
13756 size_t buf_size = sizeof(NET_COMMAND) + 4 * 1024;
13757 char* buf = (char *)malloc(buf_size);
13758 assert(buf);
13759
13760 (*nc) = (NET_COMMAND*) buf;
13761
13762 /* find out if we are on a big endian system */
13763 bool bbig = ((rpc_get_hw_type() & DRI_BIG_ENDIAN) > 0);
13764
13765 char* param_ptr = (*nc)->param;
13766
13767 for (int i=0; rl.param[i].tid != 0; i++) {
13768 int tid = rl.param[i].tid;
13769 int flags = rl.param[i].flags;
13770 int arg_type = 0;
13771
13772 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13773 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13774 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13775
13776 if (bpointer)
13777 arg_type = TID_ARRAY;
13778 else
13779 arg_type = tid;
13780
13781 /* floats are passed as doubles, at least under NT */
13782 if (tid == TID_FLOAT && !bpointer)
13783 arg_type = TID_DOUBLE;
13784
13785 /* get pointer to argument */
13786 //char arg[8];
13787 //rpc_va_arg(&ap, arg_type, arg);
13788
13789 char* arg = args[i];
13790
13791 /* shift 1- and 2-byte parameters to the LSB on big endian systems */
13792 if (bbig) {
13793 if (tid == TID_UINT8 || tid == TID_CHAR || tid == TID_INT8) {
13794 arg[0] = arg[3];
13795 }
13796 if (tid == TID_UINT16 || tid == TID_INT16) {
13797 arg[0] = arg[2];
13798 arg[1] = arg[3];
13799 }
13800 }
13801
13802 if (flags & RPC_IN) {
13803 int arg_size = 0;
13804
13805 if (bpointer)
13806 arg_size = rpc_tid_size(tid);
13807 else
13808 arg_size = rpc_tid_size(arg_type);
13809
13810 void* parg = (void *) *((void **) arg);
13811
13812 /* for strings, the argument size depends on the string length */
13813 if ((tid == TID_STRING) && (flags & RPC_CXX)) {
13814 std::string* s = (std::string*)parg;
13815 arg_size = 1 + s->length();
13816 parg = (void*)s->c_str();
13817 bpointer = TRUE;
13818 //printf("STRING %p, len %zu, [%s]\n", s, s->length(), s->c_str());
13819 } else if (tid == TID_STRING || tid == TID_LINK) {
13820 arg_size = 1 + strlen((char *) *((char **) arg));
13821 }
13822
13823 /* for varibale length arrays, the size is given by
13824 the next parameter on the stack */
13825 if (flags & RPC_VARARRAY) {
13826 //va_list aptmp;
13828 //va_copy(aptmp, ap);
13829
13830 //char arg_tmp[8];
13831 //rpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
13832
13833 if (flags & RPC_CXX) {
13834 std::vector<char>* pv = (std::vector<char>*)parg;
13835 arg_size = pv->size();
13836 parg = (void*)pv->data();
13837 bpointer = TRUE;
13838 //printf("VECTOR %p, size %zu\n", pv, pv->size());
13839
13840 *((INT *) param_ptr) = arg_size; // NB: for std:vector<char> data, pass true data size. it is safe because decoder always aligns it themselves.
13841
13842 } else {
13843 const char* arg_tmp = args[i+1];
13844
13845 /* for (RPC_IN+RPC_OUT) parameters, size argument is a pointer */
13846 if (flags & RPC_OUT) {
13847 arg_size = *((INT *) *((void **) arg_tmp));
13848 } else {
13849 arg_size = *((INT *) arg_tmp);
13850 }
13851
13852 *((INT *) param_ptr) = ALIGN8(arg_size);
13853 }
13854
13855 param_ptr += ALIGN8(sizeof(INT));
13856
13857 //va_end(aptmp);
13858 }
13859
13860 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13861 arg_size = rl.param[i].n;
13862
13863 /* always align parameter size */
13864 int param_size = ALIGN8(arg_size);
13865
13866 {
13867 size_t param_offset = (char *) param_ptr - (char *)(*nc);
13868
13869 if (param_offset + param_size + 16 > buf_size) {
13870 size_t new_size = param_offset + param_size + 1024;
13871 //printf("resize nc %zu to %zu\n", buf_size, new_size);
13872 buf = (char *) realloc(buf, new_size);
13873 assert(buf);
13874 buf_size = new_size;
13875 (*nc) = (NET_COMMAND*) buf;
13876 param_ptr = buf + param_offset;
13877 }
13878 }
13879
13880 if (bpointer) {
13881 if (debug) {
13882 printf("encode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, param_size %3d, memcpy pointer %3d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13883 }
13884 memcpy(param_ptr, parg, arg_size);
13885 } else if (tid == TID_FLOAT) {
13886 if (debug) {
13887 printf("encode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, param_size %3d, double->float\n", i, flags, tid, arg_type, arg_size, param_size);
13888 }
13889 /* floats are passed as doubles on most systems */
13890 *((float *) param_ptr) = (float) *((double *) arg);
13891 } else {
13892 if (debug) {
13893 printf("encode param %2d, flags 0x%02x, tid %2d, arg_type %2d, arg_size %3d, param_size %3d, memcpy %3d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13894 }
13895 memcpy(param_ptr, arg, arg_size);
13896 }
13897
13898 param_ptr += param_size;
13899 }
13900 }
13901
13902 (*nc)->header.param_size = (POINTER_T) param_ptr - (POINTER_T) (*nc)->param;
13903
13904 if (debug)
13905 printf("encode rpc_id %d \"%s\" buf_size %d, param_size %d\n", rl.id, rl.name, (int)buf_size, (*nc)->header.param_size);
13906}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_check_allowed_host()

INT rpc_check_allowed_host ( const char *  hostname)

Definition at line 16736 of file midas.cxx.

16747{
16748 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
16749
16751 return RPC_SUCCESS;
16752
16753 if (strcmp(hostname, "localhost") == 0)
16754 return RPC_SUCCESS;
16755
16756 if (strcmp(hostname, "localhost.localdomain") == 0)
16757 return RPC_SUCCESS;
16758
16759 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
16760 return RPC_SUCCESS;
16761
16762 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
16763 return RPC_SUCCESS;
16764
16766
16767 gAllowedHostsMutex.lock();
16768
16769 for (const auto& h: gAllowedHosts) {
16770 if (h == hostname) {
16772 break;
16773 }
16774 }
16775
16776 gAllowedHostsMutex.unlock();
16777
16778 //if (status != RPC_SUCCESS)
16779 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
16780
16781 return status;
16782}
#define RPC_NOT_REGISTERED
Definition midas.h:705
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_check_channels()

INT rpc_check_channels ( void  )

Definition at line 17756 of file midas.cxx.

17774{
17775 INT status;
17776 NET_COMMAND nc;
17777 fd_set readfds;
17778 struct timeval timeout;
17779
17780 //printf("rpc_check_channels!\n");
17781
17782 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
17783 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
17785 if (sa == NULL)
17786 continue;
17787
17788 if (sa->watchdog_timeout == 0) {
17789 continue;
17790 }
17791
17792 DWORD elapsed = ss_millitime() - sa->last_activity;
17793
17794 //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
17795
17796 if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
17797
17798 //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
17799
17800 /* send a watchdog message */
17802 nc.header.param_size = 0;
17803
17804 int convert_flags = sa->convert_flags;
17805 if (convert_flags) {
17808 }
17809
17810 /* send the header to the client */
17811 int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
17812
17813 if (i < 0) {
17814 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
17815 sa->prog_name.c_str(),
17816 sa->host_name.c_str(),
17817 sa->watchdog_timeout / 1000,
17818 i);
17819
17820 /* disconnect from experiment */
17821 if (rpc_is_mserver()) {
17823 return RPC_NET_ERROR;
17824 }
17825
17826 sa->close();
17827 return RPC_NET_ERROR;
17828 }
17829
17830 DWORD timeout_end_ms = ss_millitime() + sa->watchdog_timeout;
17831
17832 while (1) {
17833 FD_ZERO(&readfds);
17834 FD_SET(sa->send_sock, &readfds);
17835 FD_SET(sa->recv_sock, &readfds);
17836
17837 timeout.tv_sec = 1;
17838 timeout.tv_usec = 0;
17839
17840 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
17841
17842 DWORD now = ss_millitime();
17843
17844 //printf("waiting for reply: %d %d, diff %d, select() status %d\n", now, timeout_end_ms, timeout_end_ms - now, status);
17845
17846 if (now > timeout_end_ms) // timeout
17847 break;
17848
17849 if (status > 0) // select has something to read
17850 break;
17851
17852 // select() returned 0, timeout
17853 // select() returned -1, error, likely EAGAIN or EINTR
17854
17857 }
17858
17859 if (!FD_ISSET(sa->send_sock, &readfds) &&
17860 !FD_ISSET(sa->recv_sock, &readfds)) {
17861
17862 cm_msg(MERROR, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
17863 sa->prog_name.c_str(),
17864 sa->host_name.c_str(),
17865 sa->watchdog_timeout / 1000);
17866
17867 /* disconnect from experiment */
17868 if (rpc_is_mserver()) {
17870 return RPC_NET_ERROR;
17871 }
17872
17873 sa->close();
17874 return RPC_NET_ERROR;
17875 }
17876
17877 /* receive result on send socket */
17878 if (FD_ISSET(sa->send_sock, &readfds)) {
17879 i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
17880 if (i <= 0) {
17881 cm_msg(MERROR, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
17882 sa->prog_name.c_str(),
17883 sa->host_name.c_str(),
17884 sa->watchdog_timeout / 1000,
17885 i);
17886
17887 /* disconnect from experiment */
17888 if (rpc_is_mserver()) {
17890 return RPC_NET_ERROR;
17891 }
17892
17893 sa->close();
17894 return RPC_NET_ERROR;
17895 }
17896 }
17897 }
17898 }
17899 }
17900
17901 return RPC_SUCCESS;
17902}
INT cm_periodic_tasks()
Definition midas.cxx:5653
INT cm_disconnect_experiment(void)
Definition midas.cxx:2918
#define MINFO
Definition midas.h:560
#define FD_SETSIZE
Definition msystem.h:206
#define MSG_WATCHDOG
Definition msystem.h:307
DWORD ss_millitime()
Definition system.cxx:3472
INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5533
INT cm_msg_flush_buffer()
Definition midas.cxx:889
bool rpc_is_mserver(void)
Definition midas.cxx:13051
#define RPC_OUTGOING
Definition midas.h:1520
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_clear_allowed_hosts()

INT rpc_clear_allowed_hosts ( void  )

Definition at line 16682 of file midas.cxx.

16698{
16699 gAllowedHostsMutex.lock();
16700 gAllowedHosts.clear();
16701 gAllowedHostsEnabled = false;
16702 gAllowedHostsMutex.unlock();
16703 return RPC_SUCCESS;
16704}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_accept()

INT rpc_client_accept ( int  lsock)

Definition at line 17070 of file midas.cxx.

17091{
17092 INT i, status;
17093 INT client_hw_type = 0, hw_type;
17094 std::string client_program;
17095 std::string host_name;
17096 INT convert_flags;
17097 char net_buffer[256], *p;
17098
17099 int sock = accept(lsock, NULL, NULL);
17100
17101 if (sock == -1)
17102 return RPC_NET_ERROR;
17103
17104 /* check access control list */
17107
17108 if (status != RPC_SUCCESS) {
17109 ss_socket_close(&sock);
17110 return RPC_NET_ERROR;
17111 }
17112 }
17113
17114 host_name = "(unknown)";
17115 client_program = "(unknown)";
17116
17117 /* receive string with timeout */
17118 i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
17119 if (i <= 0) {
17120 ss_socket_close(&sock);
17121 return RPC_NET_ERROR;
17122 }
17123
17124 /* get remote computer info */
17125 p = strtok(net_buffer, " ");
17126 if (p != NULL) {
17127 client_hw_type = atoi(p);
17128 p = strtok(NULL, " ");
17129 }
17130 if (p != NULL) {
17131 //version = atoi(p);
17132 p = strtok(NULL, " ");
17133 }
17134 if (p != NULL) {
17135 client_program = p;
17136 p = strtok(NULL, " ");
17137 }
17138 if (p != NULL) {
17139 host_name = p;
17140 p = strtok(NULL, " ");
17141 }
17142
17143 //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
17144
17146
17147 /* save information in _server_acception structure */
17148 sa->recv_sock = sock;
17149 sa->send_sock = 0;
17150 sa->event_sock = 0;
17151 sa->remote_hw_type = client_hw_type;
17152 sa->host_name = host_name;
17153 sa->prog_name = client_program;
17155 sa->watchdog_timeout = 0;
17156 sa->is_mserver = FALSE;
17157
17158 /* send my own computer id */
17159 hw_type = rpc_get_hw_type();
17160 std::string str = msprintf("%d %s", hw_type, cm_get_version());
17161 status = send(sock, str.c_str(), str.length() + 1, 0);
17162 if (status != (INT) str.length() + 1)
17163 return RPC_NET_ERROR;
17164
17165 rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
17166 sa->convert_flags = convert_flags;
17167
17169
17170 return RPC_SUCCESS;
17171}
const char * cm_get_version()
Definition midas.cxx:1526
INT ss_suspend_set_server_acceptions(RPC_SERVER_ACCEPTION_LIST *acceptions)
Definition system.cxx:4377
INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
Definition system.cxx:5478
void rpc_calc_convert_flags(INT hw_type, INT remote_hw_type, INT *convert_flags)
Definition midas.cxx:11816
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition midas.cxx:11751
static INT rpc_socket_check_allowed_host(int sock)
Definition midas.cxx:16785
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
std::string msprintf(const char *format,...)
Definition midas.cxx:419
char str[256]
Definition odbhist.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_call()

INT rpc_client_call ( HNDLE  hConn,
DWORD  routine_id,
  ... 
)

Definition at line 14028 of file midas.cxx.

14053{
14055
14056 if (!c) {
14057 cm_msg(MERROR, "rpc_client_call", "invalid rpc connection handle %d", hConn);
14058 return RPC_NO_CONNECTION;
14059 }
14060
14061 //printf("rpc_client_call: handle %d, connection: ", hConn);
14062 //c->print();
14063 //printf("\n");
14064
14065 INT i, status;
14066
14067 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
14068 routine_id &= ~RPC_NO_REPLY;
14069
14070 //if (rpc_no_reply)
14071 // printf("rpc_client_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
14072
14073 // make local copy of the client name just in case _client_connection is erased by another thread
14074
14075 /* find rpc_index */
14076
14077 RPC_LIST rpc_entry;
14078 bool rpc_cxx = false;
14079
14080 status = rpc_find_rpc(routine_id, &rpc_entry, &rpc_cxx);
14081
14082 if (status != RPC_SUCCESS) {
14083 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" with invalid RPC ID %d", c->client_name.c_str(), c->host_name.c_str(), routine_id);
14084 c->mutex.unlock();
14085 return RPC_INVALID_ID;
14086 }
14087
14088 const char *rpc_name = rpc_entry.name;
14089
14090 NET_COMMAND *nc = NULL;
14091
14092 /* examine variable argument list and convert it to parameter array */
14093 va_list ap;
14094 va_start(ap, routine_id);
14095
14096 if (rpc_cxx)
14097 rpc_call_encode_cxx(ap, rpc_entry, &nc);
14098 else
14099 rpc_call_encode(ap, rpc_entry, &nc);
14100
14101 va_end(ap);
14102
14103 nc->header.routine_id = routine_id;
14104
14105 if (rpc_no_reply)
14107
14108 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
14109
14110 /* in FAST TCP mode, only send call and return immediately */
14111 if (rpc_no_reply) {
14112 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
14113
14114 if (i != send_size) {
14115 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": send_tcp() failed", c->client_name.c_str(), c->host_name.c_str(), rpc_name);
14116 free(nc);
14117 c->mutex.unlock();
14118 return RPC_NET_ERROR;
14119 }
14120
14121 free(nc);
14122
14123 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN) {
14124 //printf("rpc_client_call: routine_id %d is RPC_ID_EXIT %d or RPC_ID_SHUTDOWN %d, closing connection: ", routine_id, RPC_ID_EXIT, RPC_ID_SHUTDOWN);
14125 //c->print();
14126 //printf("\n");
14127 c->close_locked();
14128 }
14129
14130 c->mutex.unlock();
14131 return RPC_SUCCESS;
14132 }
14133
14134 /* in TCP mode, send and wait for reply on send socket */
14135 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
14136 if (i != send_size) {
14137 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": send_tcp() failed", c->client_name.c_str(), c->host_name.c_str(), rpc_name);
14138 c->mutex.unlock();
14139 return RPC_NET_ERROR;
14140 }
14141
14142 free(nc);
14143 nc = NULL;
14144
14145 bool restore_watchdog_timeout = false;
14146 BOOL watchdog_call;
14147 DWORD watchdog_timeout;
14148 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
14149
14150 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, c->rpc_timeout);
14151
14152 if (c->rpc_timeout >= (int) watchdog_timeout) {
14153 restore_watchdog_timeout = true;
14154 cm_set_watchdog_params(watchdog_call, c->rpc_timeout + 1000);
14155 }
14156
14157 DWORD rpc_status = 0;
14158 DWORD buf_size = 0;
14159 char* buf = NULL;
14160
14161 /* receive result on send socket */
14162 status = ss_recv_net_command(c->send_sock, &rpc_status, &buf_size, &buf, c->rpc_timeout);
14163
14164 if (restore_watchdog_timeout) {
14165 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
14166 }
14167
14168 if (status == SS_TIMEOUT) {
14169 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": timeout waiting for reply", c->client_name.c_str(), c->host_name.c_str(), rpc_name);
14170 if (buf)
14171 free(buf);
14172 c->mutex.unlock();
14173 return RPC_TIMEOUT;
14174 }
14175
14176 if (status != SS_SUCCESS) {
14177 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": error, ss_recv_net_command() status %d", c->client_name.c_str(), c->host_name.c_str(), rpc_name, status);
14178 if (buf)
14179 free(buf);
14180 c->mutex.unlock();
14181 return RPC_NET_ERROR;
14182 }
14183
14184 c->mutex.unlock();
14185
14186 if (rpc_status == RPC_INVALID_ID) {
14187 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": error, unknown RPC, status %d", c->client_name.c_str(), c->host_name.c_str(), rpc_name, rpc_status);
14188 if (buf)
14189 free(buf);
14190 return rpc_status;
14191 }
14192
14193 /* extract result variables and place it to argument list */
14194
14195 va_start(ap, routine_id);
14196
14197 if (rpc_cxx)
14198 status = rpc_call_decode_cxx(ap, rpc_entry, buf, buf_size);
14199 else
14200 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
14201
14202 if (status != RPC_SUCCESS) {
14203 rpc_status = status;
14204 }
14205
14206 va_end(ap);
14207
14208 if (buf)
14209 free(buf);
14210 buf = NULL;
14211 buf_size = 0;
14212
14213 return rpc_status;
14214}
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3355
#define RPC_NO_CONNECTION
Definition midas.h:701
#define RPC_ID_EXIT
Definition mrpc.h:141
#define RPC_ID_SHUTDOWN
Definition mrpc.h:140
static RPC_CLIENT_CONNECTION * rpc_get_locked_client_connection(HNDLE hConn)
Definition midas.cxx:12845
char c
Definition system.cxx:1312
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_check()

void rpc_client_check ( void  )

Definition at line 12503 of file midas.cxx.

12511{
12512#if 0
12513 for (i = 0; i < MAX_RPC_CONNECTION; i++)
12514 if (_client_connection[i].send_sock != 0)
12515 printf("slot %d, checking client %s socket %d, connected %d\n", i, _client_connection[i].client_name, _client_connection[i].send_sock, _client_connection[i].connected);
12516#endif
12517
12518 std::lock_guard<std::mutex> guard(_client_connections_mutex);
12519
12520 /* check for broken connections */
12521 for (unsigned i = 0; i < _client_connections.size(); i++) {
12523 if (c && c->connected) {
12524 std::lock_guard<std::mutex> cguard(c->mutex);
12525
12526 if (!c->connected) {
12527 // implicit unlock
12528 continue;
12529 }
12530
12531 //printf("rpc_client_check: connection %d: ", i);
12532 //c->print();
12533 //printf("\n");
12534
12535 int ok = 0;
12536
12537 fd_set readfds;
12538 FD_ZERO(&readfds);
12539 FD_SET(c->send_sock, &readfds);
12540
12541 struct timeval timeout;
12542 timeout.tv_sec = 0;
12543 timeout.tv_usec = 0;
12544
12545 int status;
12546
12547#ifdef OS_WINNT
12548 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12549#else
12550 do {
12551 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12552 } while (status == -1 && errno == EINTR); /* dont return if an alarm signal was cought */
12553#endif
12554
12555 if (!FD_ISSET(c->send_sock, &readfds)) {
12556 // implicit unlock
12557 continue;
12558 }
12559
12560 char buffer[64];
12561
12562 status = recv(c->send_sock, (char *) buffer, sizeof(buffer), MSG_PEEK);
12563 //printf("recv %d status %d, errno %d (%s)\n", sock, status, errno, strerror(errno));
12564
12565 if (status < 0) {
12566#ifndef OS_WINNT
12567 if (errno == EAGAIN) { // still connected
12568 ok = 1;
12569 } else
12570#endif
12571 {
12572 // connection error
12573 cm_msg(MERROR, "rpc_client_check",
12574 "RPC client connection to \"%s\" on host \"%s\" is broken, recv() errno %d (%s)",
12575 c->client_name.c_str(),
12576 c->host_name.c_str(),
12577 errno, strerror(errno));
12578 ok = 0;
12579 }
12580 } else if (status == 0) {
12581 // connection closed by remote end without sending an EXIT message
12582 // this can happen if the remote end has crashed, so this message
12583 // is still necessary as a useful diagnostic for unexpected crashes
12584 // of midas programs. K.O.
12585 cm_msg(MINFO, "rpc_client_check", "RPC client connection to \"%s\" on host \"%s\" unexpectedly closed", c->client_name.c_str(), c->host_name.c_str());
12586 ok = 0;
12587 } else {
12588 // read some data
12589 ok = 1;
12590 if (equal_ustring(buffer, "EXIT")) {
12591 /* normal exit */
12592 ok = 0;
12593 }
12594 }
12595
12596 if (!ok) {
12597 //printf("rpc_client_check: closing connection %d: ", i);
12598 //c->print();
12599 //printf("\n");
12600
12601 // connection lost, close the socket
12602 c->close_locked();
12603 }
12604
12605 // implicit unlock
12606 }
12607 }
12608
12609 // implicit unlock of _client_connections_mutex
12610}
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3780
static std::mutex _client_connections_mutex
Definition midas.cxx:11736
static std::vector< RPC_CLIENT_CONNECTION * > _client_connections
Definition midas.cxx:11737
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_connect()

INT rpc_client_connect ( const char *  host_name,
INT  port,
const char *  client_name,
HNDLE hConnection 
)

Definition at line 12245 of file midas.cxx.

12268{
12269 INT i, status;
12270 bool debug = false;
12271
12272 /* check if cm_connect_experiment was called */
12273 if (_client_name.length() == 0) {
12274 cm_msg(MERROR, "rpc_client_connect", "cm_connect_experiment/rpc_set_name not called");
12275 return RPC_NOT_REGISTERED;
12276 }
12277
12278 /* refuse connection to port 0 */
12279 if (port == 0) {
12280 cm_msg(MERROR, "rpc_client_connect", "invalid port %d", port);
12281 return RPC_NET_ERROR;
12282 }
12283
12284 RPC_CLIENT_CONNECTION* c = NULL;
12285
12286 static std::mutex gHostnameMutex;
12287
12288 {
12289 std::lock_guard<std::mutex> guard(_client_connections_mutex);
12290
12291 if (debug) {
12292 printf("rpc_client_connect: host \"%s\", port %d, client \"%s\"\n", host_name, port, client_name);
12293 for (size_t i = 0; i < _client_connections.size(); i++) {
12294 if (_client_connections[i]) {
12295 printf("client connection %d: ", (int)i);
12296 _client_connections[i]->print();
12297 printf("\n");
12298 }
12299 }
12300 }
12301
12302 // slot with index 0 is not used, fill it with a NULL
12303
12304 if (_client_connections.empty()) {
12305 _client_connections.push_back(NULL);
12306 }
12307
12308 bool hostname_locked = false;
12309
12310 /* check if connection already exists */
12311 for (size_t i = 1; i < _client_connections.size(); i++) {
12313 if (c && c->connected) {
12314
12315 if (!hostname_locked) {
12316 gHostnameMutex.lock();
12317 hostname_locked = true;
12318 }
12319
12320 if ((c->host_name == host_name) && (c->port == port)) {
12321 // NB: we must release the hostname lock before taking
12322 // c->mutex to avoid a locking order inversion deadlock:
12323 // later on we lock the hostname mutex while holding the c->mutex
12324 gHostnameMutex.unlock();
12325 hostname_locked = false;
12326 std::lock_guard<std::mutex> cguard(c->mutex);
12327 // check if socket is still connected
12328 if (c->connected) {
12329 // found connection slot with matching hostname and port number
12330 status = ss_socket_wait(c->send_sock, 0);
12331 if (status == SS_TIMEOUT) { // yes, still connected and empty
12332 // so reuse it connection
12333 *hConnection = c->index;
12334 if (debug) {
12335 printf("already connected: ");
12336 c->print();
12337 printf("\n");
12338 }
12339 // implicit unlock of c->mutex
12340 // gHostnameLock is not locked here
12341 return RPC_SUCCESS;
12342 }
12343 //cm_msg(MINFO, "rpc_client_connect", "Stale connection to \"%s\" on host %s is closed", _client_connection[i].client_name, _client_connection[i].host_name);
12344 c->close_locked();
12345 }
12346 // implicit unlock of c->mutex
12347 }
12348 }
12349 }
12350
12351 if (hostname_locked) {
12352 gHostnameMutex.unlock();
12353 hostname_locked = false;
12354 }
12355
12356 // only start reusing connections once we have
12357 // a good number of slots allocated.
12358 if (_client_connections.size() > 10) {
12359 static int last_reused = 0;
12360
12361 int size = _client_connections.size();
12362 for (int j = 1; j < size; j++) {
12363 int i = (last_reused + j) % size;
12364 if (_client_connections[i] && !_client_connections[i]->connected) {
12366 if (debug) {
12367 printf("last reused %d, reusing slot %d: ", last_reused, (int)i);
12368 c->print();
12369 printf("\n");
12370 }
12371 last_reused = i;
12372 break;
12373 }
12374 }
12375 }
12376
12377 // no slots to reuse, allocate a new slot.
12378 if (!c) {
12380
12381 // if empty slot not found, add to end of array
12382 c->index = _client_connections.size();
12383 _client_connections.push_back(c);
12384
12385 if (debug) {
12386 printf("new connection appended to array: ");
12387 c->print();
12388 printf("\n");
12389 }
12390 }
12391
12392 c->mutex.lock();
12393 c->connected = true; // rpc_client_connect() in another thread may try to grab this slot
12394
12395 // done with the array of connections
12396 // implicit unlock of _client_connections_mutex
12397 }
12398
12399 // locked connection slot for new connection
12400 assert(c != NULL);
12401
12402 std::string errmsg;
12403
12404 /* create a new socket for connecting to remote server */
12405 status = ss_socket_connect_tcp(host_name, port, &c->send_sock, &errmsg);
12406 if (status != SS_SUCCESS) {
12407 cm_msg(MERROR, "rpc_client_connect", "cannot connect to \"%s\" port %d: %s", host_name, port, errmsg.c_str());
12408 c->mutex.unlock();
12409 return RPC_NET_ERROR;
12410 }
12411
12412 gHostnameMutex.lock();
12413
12414 c->host_name = host_name;
12415 c->port = port;
12416
12417 gHostnameMutex.unlock();
12418
12419 c->client_name = client_name;
12420 c->rpc_timeout = DEFAULT_RPC_TIMEOUT;
12421
12422 /* set TCP_NODELAY option for better performance */
12423 i = 1;
12424 setsockopt(c->send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
12425
12426 /* send local computer info */
12427 std::string local_prog_name = rpc_get_name();
12428 std::string local_host_name = ss_gethostname();
12429
12430 int hw_type = rpc_get_hw_type();
12431
12432 std::string cstr = msprintf("%d %s %s %s", hw_type, cm_get_version(), local_prog_name.c_str(), local_host_name.c_str());
12433
12434 int size = cstr.length() + 1;
12435 i = send(c->send_sock, cstr.c_str(), size, 0);
12436 if (i < 0 || i != size) {
12437 cm_msg(MERROR, "rpc_client_connect", "cannot send %d bytes, send() returned %d, errno %d (%s)", size, i, errno, strerror(errno));
12438 c->mutex.unlock();
12439 return RPC_NET_ERROR;
12440 }
12441
12442 bool restore_watchdog_timeout = false;
12443 BOOL watchdog_call;
12444 DWORD watchdog_timeout;
12445 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
12446
12447 //printf("watchdog timeout: %d, rpc_connect_timeout: %d\n", watchdog_timeout, _rpc_connect_timeout);
12448
12449 if (_rpc_connect_timeout >= (int) watchdog_timeout) {
12450 restore_watchdog_timeout = true;
12451 cm_set_watchdog_params(watchdog_call, _rpc_connect_timeout + 1000);
12452 }
12453
12454 char str[256];
12455
12456 /* receive remote computer info */
12457 i = recv_string(c->send_sock, str, sizeof(str), _rpc_connect_timeout);
12458
12459 if (restore_watchdog_timeout) {
12460 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
12461 }
12462
12463 if (i <= 0) {
12464 cm_msg(MERROR, "rpc_client_connect", "timeout waiting for server reply");
12465 c->close_locked();
12466 c->mutex.unlock();
12467 return RPC_NET_ERROR;
12468 }
12469
12470 int remote_hw_type = 0;
12471 char remote_version[32];
12472 remote_version[0] = 0;
12473 sscanf(str, "%d %s", &remote_hw_type, remote_version);
12474
12475 c->remote_hw_type = remote_hw_type;
12476
12477 /* print warning if version patch level doesn't agree */
12478 char v1[32];
12479 mstrlcpy(v1, remote_version, sizeof(v1));
12480 if (strchr(v1, '.'))
12481 if (strchr(strchr(v1, '.') + 1, '.'))
12482 *strchr(strchr(v1, '.') + 1, '.') = 0;
12483
12484 mstrlcpy(str, cm_get_version(), sizeof(str));
12485 if (strchr(str, '.'))
12486 if (strchr(strchr(str, '.') + 1, '.'))
12487 *strchr(strchr(str, '.') + 1, '.') = 0;
12488
12489 if (strcmp(v1, str) != 0) {
12490 cm_msg(MERROR, "rpc_client_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", remote_version, cm_get_version());
12491 }
12492
12493 c->connected = true;
12494
12495 *hConnection = c->index;
12496
12497 c->mutex.unlock();
12498
12499 return RPC_SUCCESS;
12500}
std::string ss_gethostname()
Definition system.cxx:5791
int ss_socket_wait(int sock, INT millisec)
Definition system.cxx:4977
INT ss_socket_connect_tcp(const char *hostname, int tcp_port, int *sockp, std::string *error_msg_p)
Definition system.cxx:5046
std::string rpc_get_name()
Definition midas.cxx:13317
static std::string _client_name
Definition midas.cxx:1509
static int _rpc_connect_timeout
Definition midas.cxx:233
#define DEFAULT_RPC_TIMEOUT
Definition midas.h:287
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_disconnect()

INT rpc_client_disconnect ( HNDLE  hConn,
BOOL  bShutdown 
)

Definition at line 12909 of file midas.cxx.

12927{
12928 /* notify server about exit */
12929
12930 /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12931
12933
12934 return RPC_SUCCESS;
12935}
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:14028
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_dispatch()

INT rpc_client_dispatch ( int  sock)

Definition at line 12178 of file midas.cxx.

12186{
12187 INT status = 0;
12188 char net_buffer[256];
12189
12190 int n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
12191 if (n <= 0)
12192 return SS_ABORT;
12193
12194 NET_COMMAND *nc = (NET_COMMAND *) net_buffer;
12195
12196 if (nc->header.routine_id == MSG_ODB) {
12197 status = handle_msg_odb(n, nc);
12198 } else if (nc->header.routine_id == MSG_WATCHDOG) {
12199 nc->header.routine_id = 1;
12200 nc->header.param_size = 0;
12201 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
12203 } else if (nc->header.routine_id == MSG_BM) {
12204 fd_set readfds;
12205 struct timeval timeout;
12206
12207 //printf("rpc_client_dispatch: received MSG_BM!\n");
12208
12209 /* receive further messages to empty TCP queue */
12210 do {
12211 FD_ZERO(&readfds);
12212 FD_SET(sock, &readfds);
12213
12214 timeout.tv_sec = 0;
12215 timeout.tv_usec = 0;
12216
12217 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12218
12219 if (FD_ISSET(sock, &readfds)) {
12220 n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
12221 if (n <= 0)
12222 return SS_ABORT;
12223
12224 if (nc->header.routine_id == MSG_ODB) {
12225 status = handle_msg_odb(n, nc);
12226 } else if (nc->header.routine_id == MSG_WATCHDOG) {
12227 nc->header.routine_id = 1;
12228 nc->header.param_size = 0;
12229 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
12231 }
12232 }
12233
12234 } while (FD_ISSET(sock, &readfds));
12235
12236 /* poll event from server */
12238 }
12239
12240 return status;
12241}
INT bm_poll_event()
Definition midas.cxx:11367
#define SS_ABORT
Definition midas.h:678
#define MSG_BM
Definition msystem.h:302
#define MSG_ODB
Definition msystem.h:303
static int handle_msg_odb(int n, const NET_COMMAND *nc)
Definition midas.cxx:12164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_convert_data()

void rpc_convert_data ( void *  data,
INT  tid,
INT  flags,
INT  total_size,
INT  convert_flags 
)

Definition at line 11939 of file midas.cxx.

11967{
11968 /* convert array */
11969 if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11970 int single_size = rpc_tid_size(tid);
11971 /* don't convert TID_ARRAY & TID_STRUCT */
11972 if (single_size == 0)
11973 return;
11974
11975 int n = total_size / single_size;
11976
11977 for (int i = 0; i < n; i++) {
11978 char* p = (char *) data + (i * single_size);
11979 rpc_convert_single(p, tid, flags, convert_flags);
11980 }
11981 } else {
11982 rpc_convert_single(data, tid, flags, convert_flags);
11983 }
11984}
void * data
Definition mana.cxx:268
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_convert_single()

void rpc_convert_single ( void *  data,
INT  tid,
INT  flags,
INT  convert_flags 
)

Definition at line 11914 of file midas.cxx.

11914 {
11915
11916 if (convert_flags & CF_ENDIAN) {
11917 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11918 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11919 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11920 }
11921
11922 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11923 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11924 if (tid == TID_FLOAT)
11925 rpc_ieee2vax_float((float *) data);
11926 if (tid == TID_DOUBLE)
11927 rpc_ieee2vax_double((double *) data);
11928 }
11929
11930 if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11931 ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11932 if (tid == TID_FLOAT)
11933 rpc_vax2ieee_float((float *) data);
11934 if (tid == TID_DOUBLE)
11935 rpc_vax2ieee_double((double *) data);
11936 }
11937}
#define TID_BOOL
Definition midas.h:340
#define WORD_SWAP(x)
Definition msystem.h:65
#define QWORD_SWAP(x)
Definition msystem.h:86
#define DWORD_SWAP(x)
Definition msystem.h:74
void rpc_vax2ieee_float(float *var)
Definition midas.cxx:11859
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11844
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11894
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11875
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_debug_printf()

void rpc_debug_printf ( const char *  format,
  ... 
)

Definition at line 13394 of file midas.cxx.

13408{
13409 va_list argptr;
13410 char str[1000];
13411
13412 if (_debug_mode) {
13413 va_start(argptr, format);
13414 vsprintf(str, (char *) format, argptr);
13415 va_end(argptr);
13416
13417 if (_debug_print) {
13418 strcat(str, "\n");
13420 } else
13421 puts(str);
13422 }
13423}
static void(* _debug_print)(const char *)
Definition midas.cxx:229
static INT _debug_mode
Definition midas.cxx:231
Here is the caller graph for this function:

◆ rpc_deregister_functions()

INT rpc_deregister_functions ( void  )

dox

Definition at line 12103 of file midas.cxx.

12120{
12121 rpc_list_mutex.lock();
12122 rpc_list.clear();
12123 rpc_list_mutex.unlock();
12124
12125 return RPC_SUCCESS;
12126}
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11806
static std::mutex rpc_list_mutex
Definition midas.cxx:11807
Here is the caller graph for this function:

◆ rpc_execute_cxx()

static INT rpc_execute_cxx ( INT  sock,
int  xroutine_id,
const RPC_LIST rl,
char *  buffer,
INT  convert_flags 
)
static

Definition at line 15605 of file midas.cxx.

15632{
15633 INT status;
15634
15635 bool debug = false;
15636
15637 /* extract pointer array to parameters */
15638 NET_COMMAND* nc_in = (NET_COMMAND *) buffer;
15639
15640 /* convert header format (byte swapping) */
15641 if (convert_flags) {
15642 rpc_convert_single(&nc_in->header.routine_id, TID_UINT32, 0, convert_flags);
15643 rpc_convert_single(&nc_in->header.param_size, TID_UINT32, 0, convert_flags);
15644 }
15645
15646 //if (nc_in->header.routine_id & RPC_NO_REPLY) {
15647 // printf("rpc_execute: routine_id %d, RPC_NO_REPLY\n", (int)(nc_in->header.routine_id & ~RPC_NO_REPLY));
15648 //}
15649
15650 /* no result return as requested */
15651 if (nc_in->header.routine_id & RPC_NO_REPLY)
15652 sock = 0;
15653
15654 int routine_id = nc_in->header.routine_id & ~RPC_NO_REPLY;
15655
15656 assert(xroutine_id == routine_id);
15657
15658#if 0
15659 if (routine_id == RPC_TEST2)
15660 debug = true;
15661
15662 if (routine_id == RPC_TEST2_CXX)
15663 debug = true;
15664
15665 if (routine_id == RPC_TEST3_CXX)
15666 debug = true;
15667
15668 if (routine_id == RPC_TEST4_CXX)
15669 debug = true;
15670#endif
15671
15672 /* find entry in rpc_list */
15673
15674 char* in_param_ptr = (char*)nc_in->param;
15675
15676 if (debug)
15677 printf("rpc_execute_cxx: routine_id %d, name \"%s\"\n", routine_id, rl.name);
15678
15679 void *prpc_param[MAX_RPC_PARAMS];
15680
15681 size_t in_param_size[MAX_RPC_PARAMS];
15682 size_t in_param_offset[MAX_RPC_PARAMS];
15683
15684 std::vector<RPE> params;
15685
15686 int nparams = 0;
15687 for (int i = 0; rl.param[i].tid != 0; i++) {
15688 nparams++;
15689 }
15690
15691 params.resize(nparams);
15692
15693 size_t in_offset = 0;
15694
15695 for (int i = 0; i < nparams; i++) {
15696 in_param_size[i] = 0;
15697 in_param_offset[i] = 0;
15698
15699 int tid = rl.param[i].tid;
15700 int flags = rl.param[i].flags;
15701
15702 if (flags & RPC_IN) {
15703 int arg_size = rpc_tid_size(tid);
15704
15705 if (tid == TID_STRING || tid == TID_LINK) {
15706 arg_size = 1 + strlen((char *) (in_param_ptr));
15707 }
15708
15709 if (flags & RPC_VARARRAY) {
15710 /* for arrays, the size is stored as a INT in front of the array */
15711 int arg_size_align8 = *((INT *) in_param_ptr);
15712 if (convert_flags)
15713 rpc_convert_single(&arg_size_align8, TID_INT32, 0, convert_flags);
15714 in_param_ptr += ALIGN8(sizeof(INT));
15715 in_offset += ALIGN8(sizeof(INT));
15716 if (flags & RPC_CXX) {
15717 /* for std::vector<char> data, it is the true length of the array */
15718 arg_size = arg_size_align8;
15719 } else {
15720 /* true size is stored in the next parameter */
15721 arg_size = *((INT *) (((char*)in_param_ptr) + ALIGN8(arg_size_align8))); // NB: this ALIGN8() is redundant with ALIGN8() in the RPC client *encoder*
15722 if (convert_flags)
15723 rpc_convert_single(&arg_size, TID_INT32, 0, convert_flags);
15724 }
15725 //printf("RPC_VARARRAY: arg_size %d %d\n", arg_size_align8, arg_size);
15726
15727 if (ALIGN8(arg_size_align8) != ALIGN8(arg_size)) {
15728 cm_msg(MERROR, "rpc_execute_cxx", "RPC %d, param %d tid %d flags 0x%x size mismatch: header %d vs next param %d", routine_id, i, tid, flags, arg_size_align8, arg_size);
15729 return RPC_INVALID_ID;
15730 }
15731 }
15732
15733 if (tid == TID_STRUCT) {
15734 arg_size = rl.param[i].n;
15735 }
15736
15737 int param_size = ALIGN8(arg_size);
15738
15739 in_param_size[i] = param_size;
15740 in_param_offset[i] = in_offset;
15741
15742 params[i].offset = in_offset;
15743 params[i].arg_size = arg_size;
15744 params[i].param_size = param_size;
15745
15746 /* convert data format */
15747 if (convert_flags) {
15748 if (flags & RPC_VARARRAY) {
15749 rpc_convert_data(in_param_ptr, tid, flags, param_size, convert_flags);
15750 } else {
15751 rpc_convert_data(in_param_ptr, tid, flags, rl.param[i].n * rpc_tid_size(tid), convert_flags);
15752 }
15753 }
15754
15755 in_param_ptr += param_size;
15756 in_offset += param_size;
15757 }
15758
15759 if (flags & RPC_OUT) {
15760 params[i].out_max_size = rpc_tid_size(tid);
15761
15762 if (flags & RPC_CXX) {
15763 params[i].out_max_size = 0; // no max size!
15764 } else if (flags & RPC_VARARRAY || tid == TID_STRING) {
15765
15766 /* save maximum array length from the value of the next argument.
15767 * this means RPC_OUT arrays and strings should always be passed like this:
15768 * rpc_call(..., array_ptr, array_max_size, ...); */
15769
15770 params[i].out_max_size_offset = in_offset;
15771
15772 INT max_size = *((INT *) in_param_ptr);
15773
15774 if (convert_flags)
15775 rpc_convert_single(&max_size, TID_INT32, 0, convert_flags);
15776
15777 if (max_size < 0 || (tid == TID_STRING && max_size == 0)) {
15778 cm_msg(MERROR, "rpc_execute_cxx", "RPC %d, param %d tid %d flags 0x%x invalid maximum output size %d", routine_id, i, tid, flags, max_size);
15779 return RPC_INVALID_ID;
15780 }
15781
15782 params[i].out_max_size = max_size;
15783 }
15784
15785 if (rl.param[i].tid == TID_STRUCT) {
15786 params[i].out_max_size = rl.param[i].n;
15787 }
15788 }
15789
15790 if (flags & RPC_CXX) {
15791 if (tid == TID_STRING) {
15792 params[i].ps = new std::string;
15793 if (flags & RPC_IN) {
15794 *(params[i].ps) = (char*)nc_in->param + in_param_offset[i];
15795 //printf("STRING %d decode [%s]\n", i, (char*)nc_in->param + in_param_offset[i]);
15796 }
15797 prpc_param[i] = (void*) params[i].ps;
15798 } else if (tid == TID_ARRAY) {
15799 params[i].pv = new std::vector<char>;
15800 if (flags & RPC_IN) {
15801 params[i].pv->insert(params[i].pv->end(), (char*)nc_in->param + in_param_offset[i], (char*)nc_in->param + in_param_offset[i] + params[i].arg_size);
15802 //printf("VECTOR %d decode %zu bytes\n", i, params[i].pv->size());
15803 }
15804 prpc_param[i] = (void*) params[i].pv;
15805 } else {
15806 cm_msg(MERROR, "rpc_execute_cxx", "RPC %d: param %d tid %d flags 0x%x, TID not compatible with flag RPC_CXX", routine_id, i, tid, flags);
15807 return RPC_INVALID_ID;
15808 }
15809 } else {
15810 if ((flags & RPC_IN) && (flags & RPC_OUT)) {
15811 params[i].pv = new std::vector<char>;
15812 params[i].pv->insert(params[i].pv->end(), (char*)nc_in->param + in_param_offset[i], (char*)nc_in->param + in_param_offset[i] + params[i].arg_size);
15813 size_t want_size = params[i].out_max_size;
15814 //printf("param %d size %zu want %zu\n", i, params[i].pv->size(), want_size);
15815 if (params[i].pv->size() < want_size)
15816 params[i].pv->resize(want_size);
15817 prpc_param[i] = params[i].pv->data();
15818 } else if (flags & RPC_IN) {
15819 prpc_param[i] = (char*)nc_in->param + in_param_offset[i];
15820 //printf("param %d input value %d [%s]\n", i, *(int*)prpc_param[i], (char*)prpc_param[i]);
15821 } else if (flags & RPC_OUT) {
15822 params[i].pv = new std::vector<char>;
15823 params[i].pv->resize(params[i].out_max_size);
15824 prpc_param[i] = params[i].pv->data();
15825 //printf("param %d size %zu\n", i, params[i].pv->size());
15826 }
15827 }
15828
15829 if (debug)
15830 printf("rpc_execute_cxx: param %2d, tid %2d, flags 0x%04x, in %3zu+%-3zu+%-3zu, out max size %3zu at %3zu, ptr %p\n", i, tid, flags, params[i].offset, params[i].arg_size, params[i].param_size, params[i].out_max_size, params[i].out_max_size_offset, prpc_param[i]);
15831 }
15832
15833 if (debug)
15834 printf("rpc_execute_cxx: nc_in size %d, in_offset %zu\n", nc_in->header.param_size, in_offset);
15835
15836 if (routine_id == RPC_TEST2) {
15837 bool ok = true;
15838
15839 ok &= in_param_offset[ 0] == 0; ok &= in_param_size[ 0] == 8; // int_in
15840 ok &= in_param_offset[ 1] == 0; ok &= in_param_size[ 1] == 0; // int_out
15841 ok &= in_param_offset[ 2] == 8; ok &= in_param_size[ 2] == 8; // &int_inout
15842 ok &= in_param_offset[ 3] == 16; ok &= in_param_size[ 3] == 16; // string_in
15843 ok &= in_param_offset[ 4] == 0; ok &= in_param_size[ 4] == 0; // string_out
15844 ok &= in_param_offset[ 5] == 32; ok &= in_param_size[ 5] == 8; // string_out size
15845 ok &= in_param_offset[ 6] == 0; ok &= in_param_size[ 6] == 0; // string2_out
15846 ok &= in_param_offset[ 7] == 40; ok &= in_param_size[ 7] == 8; // string2_out size
15847 ok &= in_param_offset[ 8] == 48; ok &= in_param_size[ 8] == 16; // string_inout
15848 ok &= in_param_offset[ 9] == 64; ok &= in_param_size[ 9] == 8; // string_inout size
15849 ok &= in_param_offset[10] == 72; ok &= in_param_size[10] == 72; // struct_in
15850 ok &= in_param_offset[11] == 0; ok &= in_param_size[11] == 0; // struct_out
15851 ok &= in_param_offset[12] == 144; ok &= in_param_size[12] == 72; // struct_inout
15852 ok &= in_param_offset[13] == 224; ok &= in_param_size[13] == 40; // uint32_t[10] array inout
15853 ok &= in_param_offset[14] == 264; ok &= in_param_size[14] == 8; // &size
15854 ok &= in_param_offset[15] == 280; ok &= in_param_size[15] == 16; // char[10] array in
15855 ok &= in_param_offset[16] == 296; ok &= in_param_size[16] == 8; // size
15856 ok &= in_param_offset[17] == 0; ok &= in_param_size[17] == 0; // char[16] array out
15857 ok &= in_param_offset[18] == 304; ok &= in_param_size[18] == 8; // &size
15858 ok &= in_offset == 312;
15859
15860 if (!ok) {
15861 cm_msg(MERROR, "rpc_execute_cxx", "RPC_TEST2 parameters encoding error!");
15862 return RPC_INVALID_ID;
15863 }
15864 }
15865
15866 if (debug) {
15867 printf("rpc_execute_cxx: calling dispatch()\n");
15868 }
15869
15870 /*********************************\
15871 * call dispatch function *
15872 \*********************************/
15873 if (rl.dispatch)
15874 status = rl.dispatch(routine_id, prpc_param);
15875 else
15877
15878 if (debug) {
15879 printf("rpc_execute_cxx: dispatch() status %d\n", status);
15880 }
15881
15882 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN || routine_id == RPC_ID_WATCHDOG)
15884
15885 /* return immediately for closed down client connections */
15886 if (!sock && routine_id == RPC_ID_EXIT) {
15887 return SS_EXIT;
15888 }
15889
15890 if (!sock && routine_id == RPC_ID_SHUTDOWN) {
15891 return RPC_SHUTDOWN;
15892 }
15893
15894 /* Return if TCP connection broken */
15895 if (status == SS_ABORT) {
15896 return SS_ABORT;
15897 }
15898
15899 /* if sock == 0, we are in FTCP mode and may not sent results */
15900 if (!sock) {
15901 return RPC_SUCCESS;
15902 }
15903
15904 std::vector<char> v_out;
15905
15906 v_out.resize(sizeof(NET_COMMAND_HEADER));
15907
15908 for (int i = 0; i < nparams; i++) {
15909 if (rl.param[i].flags & RPC_OUT) {
15910 int tid = rl.param[i].tid;
15911 int flags = rl.param[i].flags;
15912
15913 if (flags & RPC_CXX) {
15914 if (tid == TID_STRING) {
15915 size_t arg_size = 1 + params[i].ps->length();
15916 size_t param_size = ALIGN8(arg_size);
15917
15918 if (debug)
15919 printf("rpc_execute_cxx: param %2d, std::string arg_size %zu, param_size %zu, string [%s]\n", i, arg_size, param_size, params[i].ps->c_str());
15920
15921 v_out.insert(v_out.end(), params[i].ps->c_str(), params[i].ps->c_str() + arg_size);
15922 v_out.resize(v_out.size() + param_size - arg_size); // pad to 8 bytes
15923 } else if (tid == TID_ARRAY) {
15924 size_t arg_size = params[i].pv->size();
15925 size_t param_size = ALIGN8(arg_size);
15926
15927 if (debug)
15928 printf("rpc_execute_cxx: param %2d, std::vector arg_size %zu, param_size %zu\n", i, arg_size, param_size);
15929
15930 char buf[ALIGN8(sizeof(INT))];
15931 *((INT *) buf) = arg_size; // store new array size
15932 if (convert_flags)
15933 rpc_convert_single(buf, TID_INT32, RPC_OUTGOING, convert_flags);
15934 v_out.insert(v_out.end(), buf, buf + ALIGN8(sizeof(INT))); // 8 bytes of param_size
15935 v_out.insert(v_out.end(), params[i].pv->data(), params[i].pv->data() + arg_size); // data
15936 v_out.resize(v_out.size() + param_size - arg_size); // pad data to 8 bytes
15937 } else {
15938 cm_msg(MERROR, "rpc_execute_cxx", "RPC %d: param %d tid %d flags 0x%x, TID not compatible with flag RPC_CXX", routine_id, i, tid, flags);
15939 return RPC_INVALID_ID;
15940 }
15941 } else {
15942 size_t convert_offset = 0;
15943 size_t convert_size = 0;
15944
15945 if (tid == TID_STRING) {
15946 size_t max_size = params[i].out_max_size;
15947 char* param_ptr = (char *) prpc_param[i];
15948 //printf("param %d string param [%s] max_size %zu\n", i, param_ptr, max_size);
15949 char* string_end = (char*)memchr(param_ptr, 0, max_size);
15950 size_t arg_size = string_end ? string_end - param_ptr : max_size;
15951 if (!string_end) {
15952 param_ptr[max_size - 1] = 0; // truncate!
15953 arg_size = max_size - 1;
15954 }
15955 arg_size++;
15956 size_t param_size = ALIGN8(arg_size);
15957
15958 if (debug)
15959 printf("rpc_execute_cxx: param %2d, string max_size %zu, string_size %zu, param_size %zu\n", i, max_size, arg_size, param_size);
15960
15961 v_out.insert(v_out.end(), param_ptr, param_ptr + arg_size);
15962 v_out.resize(v_out.size() + param_size - arg_size); // pad to 8 bytes
15963 } else if (flags & RPC_VARARRAY) {
15964 size_t max_size = params[i].out_max_size;
15965 INT arg_size_int = *((INT *) prpc_param[i + 1]);
15966 if (arg_size_int < 0 || (size_t) arg_size_int > max_size) {
15967 cm_msg(MERROR, "rpc_execute_cxx", "RPC %d, param %d output array size %d exceeds maximum size %zu", routine_id, i, arg_size_int, max_size);
15968 return RPC_EXCEED_BUFFER;
15969 }
15970 size_t arg_size = arg_size_int;
15971 char* param_ptr = (char*)prpc_param[i];
15972 size_t param_size = ALIGN8(arg_size);
15973
15974 if (debug)
15975 printf("rpc_execute_cxx: param %2d, array max_size %zu, param_size %zu\n", i, max_size, param_size);
15976
15977 char buf[ALIGN8(sizeof(INT))];
15978 *((INT *) buf) = arg_size; // store new array size
15979 if (convert_flags)
15980 rpc_convert_single(buf, TID_INT32, RPC_OUTGOING, convert_flags);
15981 v_out.insert(v_out.end(), buf, buf + ALIGN8(sizeof(INT))); // 8 bytes of param_size
15982 convert_offset = v_out.size();
15983 convert_size = arg_size;
15984 v_out.insert(v_out.end(), param_ptr, param_ptr + arg_size); // data
15985 v_out.resize(v_out.size() + param_size - arg_size); // pad data to 8 bytes
15986 } else {
15987 char* param_ptr = (char*)prpc_param[i];
15988 size_t arg_size = rpc_tid_size(tid);
15989 if (tid == TID_STRUCT)
15990 arg_size = rl.param[i].n;
15991 size_t param_size = ALIGN8(arg_size);
15992
15993 if (debug) {
15994 if (tid == TID_INT) {
15995 printf("rpc_execute_cxx: param %2d, tid %2d, arg_size %zu, param_size %zu, value %d\n", i, tid, arg_size, param_size, *(int*)param_ptr);
15996 } else {
15997 printf("rpc_execute_cxx: param %2d, tid %2d, arg_size %zu, param_size %zu\n", i, tid, arg_size, param_size);
15998 }
15999 }
16000
16001 convert_offset = v_out.size();
16002 convert_size = arg_size;
16003 v_out.insert(v_out.end(), param_ptr, param_ptr + arg_size); // data
16004 v_out.resize(v_out.size() + param_size - arg_size); // pad data to 8 bytes
16005 }
16006
16007 /* convert data format */
16008 if (convert_flags) {
16009 if (flags & RPC_VARARRAY)
16010 rpc_convert_data(v_out.data()+convert_offset, tid, rl.param[i].flags | RPC_OUTGOING, convert_size, convert_flags);
16011 else
16012 rpc_convert_data(v_out.data()+convert_offset, tid, rl.param[i].flags | RPC_OUTGOING, rl.param[i].n * rpc_tid_size(tid), convert_flags);
16013 }
16014 }
16015 }
16016 }
16017
16018 NET_COMMAND* nc_out = (NET_COMMAND*)v_out.data();
16019
16020 /* send return parameters */
16021 nc_out->header.routine_id = status;
16022 nc_out->header.param_size = v_out.size() - sizeof(NET_COMMAND_HEADER);
16023
16024
16025 /* convert header format (byte swapping) if necessary */
16026 if (convert_flags) {
16027 rpc_convert_single(&nc_out->header.routine_id, TID_UINT32, RPC_OUTGOING, convert_flags);
16028 rpc_convert_single(&nc_out->header.param_size, TID_UINT32, RPC_OUTGOING, convert_flags);
16029 }
16030
16031 status = send_tcp(sock, v_out.data(), v_out.size(), 0);
16032
16033 if (status < 0) {
16034 cm_msg(MERROR, "rpc_execute_cxx", "send_tcp() failed, status %d", status);
16035 return RPC_NET_ERROR;
16036 }
16037
16038 if (debug)
16039 printf("rpc_execute_cxx: send_tcp() sent %d bytes\n", status);
16040
16041 /* return SS_EXIT if RPC_EXIT is called */
16042 if (routine_id == RPC_ID_EXIT)
16043 return SS_EXIT;
16044
16045 /* return SS_SHUTDOWN if RPC_SHUTDOWN is called */
16046 if (routine_id == RPC_ID_SHUTDOWN)
16047 return RPC_SHUTDOWN;
16048
16049 return RPC_SUCCESS;
16050}
#define SS_EXIT
Definition midas.h:679
#define RPC_SHUTDOWN
Definition midas.h:708
#define RPC_EXCEED_BUFFER
Definition midas.h:704
#define TID_INT
Definition midas.h:338
#define RPC_TEST3_CXX
Definition mrpc.h:126
void rpc_convert_data(void *data, INT tid, INT flags, INT total_size, INT convert_flags)
Definition midas.cxx:11939
#define RPC_TEST2
Definition mrpc.h:124
#define RPC_TEST4_CXX
Definition mrpc.h:127
#define RPC_ID_WATCHDOG
Definition mrpc.h:139
#define RPC_TEST2_CXX
Definition mrpc.h:125
static int offset
Definition mgd.cxx:1500
RPC_HANDLER * dispatch
Definition midas.h:1537
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_execute_old()

static INT rpc_execute_old ( INT  sock,
int  xroutine_id,
const RPC_LIST rl,
char *  buffer,
INT  convert_flags 
)
static

Definition at line 15198 of file midas.cxx.

15225{
15226 INT i, routine_id, status;
15227 char *in_param_ptr, *out_param_ptr, *last_param_ptr;
15228 INT tid, flags;
15229 NET_COMMAND *nc_in, *nc_out;
15230 INT param_size, max_size;
15231 void *prpc_param[20];
15232 char debug_line[1024], *return_buffer;
15233 int return_buffer_size;
15234 int return_buffer_tls;
15235#ifdef FIXED_BUFFER
15236 int initial_buffer_size = NET_BUFFER_SIZE;
15237#else
15238 int initial_buffer_size = 1024;
15239#endif
15240
15241 /* return buffer must must use thread local storage multi-thread servers */
15242 if (!tls_size) {
15243 tls_buffer = (TLS_POINTER *) malloc(sizeof(TLS_POINTER));
15245 tls_buffer[tls_size].buffer_size = initial_buffer_size;
15246 tls_buffer[tls_size].buffer = (char *) malloc(tls_buffer[tls_size].buffer_size);
15247 tls_size = 1;
15248 }
15249 for (i = 0; i < tls_size; i++)
15250 if (tls_buffer[i].thread_id == ss_gettid())
15251 break;
15252 if (i == tls_size) {
15253 /* new thread -> allocate new buffer */
15254 tls_buffer = (TLS_POINTER *) realloc(tls_buffer, (tls_size + 1) * sizeof(TLS_POINTER));
15256 tls_buffer[tls_size].buffer_size = initial_buffer_size;
15257 tls_buffer[tls_size].buffer = (char *) malloc(tls_buffer[tls_size].buffer_size);
15258 tls_size++;
15259 }
15260
15261 return_buffer_tls = i;
15262 return_buffer_size = tls_buffer[i].buffer_size;
15263 return_buffer = tls_buffer[i].buffer;
15264 assert(return_buffer);
15265
15266 // make valgrind happy - the RPC parameter encoder skips the alignement padding bytes
15267 // and valgrind complains that we transmit uninitialized data
15268 //memset(return_buffer, 0, return_buffer_size);
15269
15270 /* extract pointer array to parameters */
15271 nc_in = (NET_COMMAND *) buffer;
15272
15273 /* convert header format (byte swapping) */
15274 if (convert_flags) {
15275 rpc_convert_single(&nc_in->header.routine_id, TID_UINT32, 0, convert_flags);
15276 rpc_convert_single(&nc_in->header.param_size, TID_UINT32, 0, convert_flags);
15277 }
15278
15279 //if (nc_in->header.routine_id & RPC_NO_REPLY) {
15280 // printf("rpc_execute: routine_id %d, RPC_NO_REPLY\n", (int)(nc_in->header.routine_id & ~RPC_NO_REPLY));
15281 //}
15282
15283 /* no result return as requested */
15284 if (nc_in->header.routine_id & RPC_NO_REPLY)
15285 sock = 0;
15286
15287 /* find entry in rpc_list */
15288 routine_id = nc_in->header.routine_id & ~RPC_NO_REPLY;
15289
15290 assert(xroutine_id == routine_id);
15291
15292 again:
15293
15294 in_param_ptr = nc_in->param;
15295
15296 nc_out = (NET_COMMAND *) return_buffer;
15297 out_param_ptr = nc_out->param;
15298
15299 sprintf(debug_line, "%s(", rl.name);
15300
15301 for (i = 0; rl.param[i].tid != 0; i++) {
15302 tid = rl.param[i].tid;
15303 flags = rl.param[i].flags;
15304
15305 if (flags & RPC_IN) {
15306 param_size = ALIGN8(rpc_tid_size(tid));
15307
15308 if (tid == TID_STRING || tid == TID_LINK)
15309 param_size = ALIGN8(1 + strlen((char *) (in_param_ptr)));
15310
15311 if (flags & RPC_VARARRAY) {
15312 /* for arrays, the size is stored as a INT in front of the array */
15313 param_size = *((INT *) in_param_ptr);
15314 if (convert_flags)
15315 rpc_convert_single(&param_size, TID_INT32, 0, convert_flags);
15316 param_size = ALIGN8(param_size);
15317
15318 in_param_ptr += ALIGN8(sizeof(INT));
15319 }
15320
15321 if (tid == TID_STRUCT)
15322 param_size = ALIGN8(rl.param[i].n);
15323
15324 prpc_param[i] = in_param_ptr;
15325
15326 /* convert data format */
15327 if (convert_flags) {
15328 if (flags & RPC_VARARRAY)
15329 rpc_convert_data(in_param_ptr, tid, flags, param_size, convert_flags);
15330 else
15331 rpc_convert_data(in_param_ptr, tid, flags, rl.param[i].n * rpc_tid_size(tid),
15332 convert_flags);
15333 }
15334
15335 std::string str = db_sprintf(in_param_ptr, param_size, 0, rl.param[i].tid);
15336 if (rl.param[i].tid == TID_STRING) {
15337 /* check for long strings (db_create_record...) */
15338 if (strlen(debug_line) + str.length() + 2 < sizeof(debug_line)) {
15339 strcat(debug_line, "\"");
15340 strcat(debug_line, str.c_str());
15341 strcat(debug_line, "\"");
15342 } else
15343 strcat(debug_line, "...");
15344 } else
15345 strcat(debug_line, str.c_str());
15346
15347 in_param_ptr += param_size;
15348 }
15349
15350 if (flags & RPC_OUT) {
15351 param_size = ALIGN8(rpc_tid_size(tid));
15352
15353 if (flags & RPC_VARARRAY || tid == TID_STRING) {
15354
15355 /* save maximum array length from the value of the next argument.
15356 * this means RPC_OUT arrays and strings should always be passed like this:
15357 * rpc_call(..., array_ptr, array_max_size, ...); */
15358
15359 max_size = *((INT *) in_param_ptr);
15360
15361 if (convert_flags)
15362 rpc_convert_single(&max_size, TID_INT32, 0, convert_flags);
15363 max_size = ALIGN8(max_size);
15364
15365 *((INT *) out_param_ptr) = max_size;
15366
15367 /* save space for return array length */
15368 out_param_ptr += ALIGN8(sizeof(INT));
15369
15370 /* use maximum array length from input */
15371 param_size = max_size;
15372 }
15373
15374 if (rl.param[i].tid == TID_STRUCT)
15375 param_size = ALIGN8(rl.param[i].n);
15376
15377 if ((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size > return_buffer_size) {
15378#ifdef FIXED_BUFFER
15379 cm_msg(MERROR, "rpc_execute",
15380 "return parameters (%d) too large for network buffer (%d)",
15381 (POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size, return_buffer_size);
15382
15383 return RPC_EXCEED_BUFFER;
15384#else
15385 int itls;
15386 int new_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size + 1024;
15387
15388#if 0
15389 cm_msg(MINFO, "rpc_execute",
15390 "rpc_execute: return parameters (%d) too large for network buffer (%d), new buffer size (%d)",
15391 (int)((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size), return_buffer_size, new_size);
15392#endif
15393
15394 itls = return_buffer_tls;
15395
15396 tls_buffer[itls].buffer_size = new_size;
15397 tls_buffer[itls].buffer = (char *) realloc(tls_buffer[itls].buffer, new_size);
15398
15399 if (!tls_buffer[itls].buffer) {
15400 cm_msg(MERROR, "rpc_execute", "Cannot allocate return buffer of size %d", new_size);
15401 return RPC_EXCEED_BUFFER;
15402 }
15403
15404 return_buffer_size = tls_buffer[itls].buffer_size;
15405 return_buffer = tls_buffer[itls].buffer;
15406 assert(return_buffer);
15407
15408 goto again;
15409#endif
15410 }
15411
15412 /* if parameter goes both directions, copy input to output */
15413 if (rl.param[i].flags & RPC_IN)
15414 memcpy(out_param_ptr, prpc_param[i], param_size);
15415
15416 if (_debug_print && !(flags & RPC_IN))
15417 strcat(debug_line, "-");
15418
15419 prpc_param[i] = out_param_ptr;
15420 out_param_ptr += param_size;
15421 }
15422
15423 if (rl.param[i + 1].tid)
15424 strcat(debug_line, ", ");
15425 }
15426
15427 //printf("predicted return size %d\n", (POINTER_T) out_param_ptr - (POINTER_T) nc_out);
15428
15429 strcat(debug_line, ")");
15430 rpc_debug_printf(debug_line);
15431
15432 last_param_ptr = out_param_ptr;
15433
15434 /*********************************\
15435 * call dispatch function *
15436 \*********************************/
15437 if (rl.dispatch)
15438 status = rl.dispatch(routine_id, prpc_param);
15439 else
15441
15442 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN || routine_id == RPC_ID_WATCHDOG)
15444
15445 /* return immediately for closed down client connections */
15446 if (!sock && routine_id == RPC_ID_EXIT)
15447 return SS_EXIT;
15448
15449 if (!sock && routine_id == RPC_ID_SHUTDOWN)
15450 return RPC_SHUTDOWN;
15451
15452 /* Return if TCP connection broken */
15453 if (status == SS_ABORT)
15454 return SS_ABORT;
15455
15456 /* if sock == 0, we are in FTCP mode and may not sent results */
15457 if (!sock)
15458 return RPC_SUCCESS;
15459
15460 /* compress variable length arrays */
15461 out_param_ptr = nc_out->param;
15462 for (i = 0; rl.param[i].tid != 0; i++)
15463 if (rl.param[i].flags & RPC_OUT) {
15464 tid = rl.param[i].tid;
15465 flags = rl.param[i].flags;
15466 param_size = ALIGN8(rpc_tid_size(tid));
15467
15468 if (tid == TID_STRING) {
15469 max_size = *((INT *) out_param_ptr);
15470 // note: RPC_OUT parameters may have been shifted in the output buffer by memmove()
15471 // and prpc_param() is now pointing to the wrong place. here we know our string data
15472 // starts right after max_size and we do not need to use prpc_param[] to find it. K.O.
15473 //const char* param_ptr = (char *) prpc_param[i];
15474 const char* param_ptr = ((char *) out_param_ptr) + ALIGN8(sizeof(INT));
15475 //printf("string param [%s] max_size %d\n", param_ptr, max_size);
15476 param_size = strlen(param_ptr) + 1;
15477 param_size = ALIGN8(param_size);
15478
15479 /* move string ALIGN8(sizeof(INT)) left */
15480 memmove(out_param_ptr, out_param_ptr + ALIGN8(sizeof(INT)), param_size);
15481
15482 /* move remaining parameters to end of string */
15483 memmove(out_param_ptr + param_size,
15484 out_param_ptr + max_size + ALIGN8(sizeof(INT)),
15485 (POINTER_T) last_param_ptr - ((POINTER_T) out_param_ptr + max_size + ALIGN8(sizeof(INT))));
15486 }
15487
15488 if (flags & RPC_VARARRAY) {
15489 /* store array length at current out_param_ptr */
15490 max_size = *((INT *) out_param_ptr);
15491 // note: RPC_OUT parameters may have been shifted in the output buffer by memmove()
15492 // and prpc_param() is now pointing to the wrong place. instead, compute location
15493 // of next parameter using max_size. K.O.
15494 // note: RPC_IN parameters are in the input buffer and we must use the prpc_param[] pointer. K.O.
15495 if (rl.param[i+1].flags & RPC_OUT)
15496 param_size = *((INT *) (out_param_ptr + ALIGN8(sizeof(INT)) + ALIGN8(max_size)));
15497 else
15498 param_size = *((INT *) prpc_param[i + 1]);
15499 *((INT *) out_param_ptr) = param_size; // store new array size
15500 if (convert_flags)
15501 rpc_convert_single(out_param_ptr, TID_INT32, RPC_OUTGOING, convert_flags);
15502
15503 out_param_ptr += ALIGN8(sizeof(INT)); // step over array size
15504
15505 param_size = ALIGN8(param_size);
15506
15507 /* move remaining parameters to end of array */
15508 memmove(out_param_ptr + param_size,
15509 out_param_ptr + max_size,
15510 (POINTER_T) last_param_ptr - ((POINTER_T) out_param_ptr + max_size));
15511 }
15512
15513 if (tid == TID_STRUCT)
15514 param_size = ALIGN8(rl.param[i].n);
15515
15516 /* convert data format */
15517 if (convert_flags) {
15518 if (flags & RPC_VARARRAY)
15519 rpc_convert_data(out_param_ptr, tid,
15520 rl.param[i].flags | RPC_OUTGOING, param_size, convert_flags);
15521 else
15522 rpc_convert_data(out_param_ptr, tid,
15523 rl.param[i].flags | RPC_OUTGOING,
15524 rl.param[i].n * rpc_tid_size(tid), convert_flags);
15525 }
15526
15527 out_param_ptr += param_size;
15528 }
15529
15530 /* send return parameters */
15531 param_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out->param;
15532 nc_out->header.routine_id = status;
15533 nc_out->header.param_size = param_size;
15534
15535 //printf("actual return size %d, buffer used %d\n", (POINTER_T) out_param_ptr - (POINTER_T) nc_out, sizeof(NET_COMMAND_HEADER) + param_size);
15536
15537 /* convert header format (byte swapping) if necessary */
15538 if (convert_flags) {
15539 rpc_convert_single(&nc_out->header.routine_id, TID_UINT32, RPC_OUTGOING, convert_flags);
15540 rpc_convert_single(&nc_out->header.param_size, TID_UINT32, RPC_OUTGOING, convert_flags);
15541 }
15542
15543 // valgrind complains about sending uninitialized data, if you care about this, uncomment
15544 // the memset(return_buffer,0) call above (search for "valgrind"). K.O.
15545
15546 status = send_tcp(sock, return_buffer, sizeof(NET_COMMAND_HEADER) + param_size, 0);
15547
15548 if (status < 0) {
15549 cm_msg(MERROR, "rpc_execute", "send_tcp() failed");
15550 return RPC_NET_ERROR;
15551 }
15552
15553 /* print return buffer */
15554/*
15555 printf("Return buffer, ID %d:\n", routine_id);
15556 for (i=0; i<param_size ; i++)
15557 {
15558 status = (char) nc_out->param[i];
15559 printf("%02X ", status);
15560 if (i%8 == 7)
15561 printf("\n");
15562 }
15563*/
15564 /* return SS_EXIT if RPC_EXIT is called */
15565 if (routine_id == RPC_ID_EXIT)
15566 return SS_EXIT;
15567
15568 /* return SS_SHUTDOWN if RPC_SHUTDOWN is called */
15569 if (routine_id == RPC_ID_SHUTDOWN)
15570 return RPC_SHUTDOWN;
15571
15572 return RPC_SUCCESS;
15573}
midas_thread_t ss_gettid(void)
Definition system.cxx:1591
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:11426
static int tls_size
Definition midas.cxx:15195
void rpc_debug_printf(const char *format,...)
Definition midas.cxx:13394
static TLS_POINTER * tls_buffer
Definition midas.cxx:15194
midas_thread_t thread_id
Definition midas.cxx:15189
int buffer_size
Definition midas.cxx:15190
char * buffer
Definition midas.cxx:15191
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_find_rpc()

static int rpc_find_rpc ( int  routine_id,
RPC_LIST pentry,
bool *  prpc_cxx 
)
static

Definition at line 14002 of file midas.cxx.

14003{
14004 rpc_list_mutex.lock();
14005
14006 for (size_t i = 0; i < rpc_list.size(); i++) {
14007 if (rpc_list[i].id == routine_id) {
14008 *pentry = rpc_list[i];
14009
14010 rpc_list_mutex.unlock();
14011
14012 *prpc_cxx = false;
14013
14014 for (int j=0; j<MAX_RPC_PARAMS; j++)
14015 if (pentry->param[j].flags & RPC_CXX)
14016 *prpc_cxx = true;
14017
14018 return RPC_SUCCESS;
14019 }
14020 }
14021
14022 rpc_list_mutex.unlock();
14023
14024 return RPC_INVALID_ID;
14025}
Here is the caller graph for this function:

◆ rpc_flush_event()

INT rpc_flush_event ( void  )

Send event residing in the TCP cache buffer filled by rpc_send_event. This routine should be called when a run is stopped.

Returns
RPC_SUCCESS, RPC_NET_ERROR

Definition at line 14588 of file midas.cxx.

14588 {
14589 return RPC_SUCCESS;
14590}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 17638 of file midas.cxx.

17652{
17653 bool has_data = ss_event_socket_has_data();
17654
17655 //printf("ss_event_socket_has_data() returned %d\n", has_data);
17656
17657 if (has_data) {
17658 if (timeout_msec == BM_NO_WAIT) {
17659 return BM_ASYNC_RETURN;
17660 } else if (timeout_msec == BM_WAIT) {
17661 return BM_ASYNC_RETURN;
17662 } else {
17663 int status = ss_suspend(timeout_msec, MSG_BM);
17664 if (status == SS_ABORT || status == SS_EXIT)
17665 return status;
17666 return BM_ASYNC_RETURN;
17667 }
17668 }
17669
17670 int status = rpc_server_receive_event(0, NULL, timeout_msec);
17671
17672 //printf("rpc_server_receive_event() status %d\n", status);
17673
17674 if (status == BM_ASYNC_RETURN) {
17675 return BM_ASYNC_RETURN;
17676 }
17677
17678 if (status == SS_ABORT || status == SS_EXIT)
17679 return status;
17680
17681 return BM_SUCCESS;
17682}
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define BM_NO_WAIT
Definition midas.h:366
#define BM_WAIT
Definition midas.h:365
INT ss_suspend(INT millisec, INT msg)
Definition system.cxx:4622
bool ss_event_socket_has_data()
Definition system.cxx:4599
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:17483
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_convert_flags() [1/2]

void rpc_get_convert_flags ( INT convert_flags)

Definition at line 11839 of file midas.cxx.

Here is the call graph for this function:

◆ rpc_get_convert_flags() [2/2]

INT rpc_get_convert_flags ( void  )

dox

Definition at line 13263 of file midas.cxx.

13274{
13277 else
13278 return 0;
13279}
Here is the caller graph for this function:

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 13067 of file midas.cxx.

13078{
13079 {
13080 {
13081 INT tmp_type, size;
13082 DWORD dummy;
13083 unsigned char *p;
13084 float f;
13085 double d;
13086
13087 tmp_type = 0;
13088
13089 /* test pointer size */
13090 size = sizeof(p);
13091 if (size == 2)
13092 tmp_type |= DRI_16;
13093 if (size == 4)
13094 tmp_type |= DRI_32;
13095 if (size == 8)
13096 tmp_type |= DRI_64;
13097
13098 /* test if little or big endian machine */
13099 dummy = 0x12345678;
13100 p = (unsigned char *) &dummy;
13101 if (*p == 0x78)
13102 tmp_type |= DRI_LITTLE_ENDIAN;
13103 else if (*p == 0x12)
13104 tmp_type |= DRI_BIG_ENDIAN;
13105 else
13106 cm_msg(MERROR, "rpc_get_option", "unknown byte order format");
13107
13108 /* floating point format */
13109 f = (float) 1.2345;
13110 dummy = 0;
13111 memcpy(&dummy, &f, sizeof(f));
13112 if ((dummy & 0xFF) == 0x19 &&
13113 ((dummy >> 8) & 0xFF) == 0x04 && ((dummy >> 16) & 0xFF) == 0x9E
13114 && ((dummy >> 24) & 0xFF) == 0x3F)
13115 tmp_type |= DRF_IEEE;
13116 else if ((dummy & 0xFF) == 0x9E &&
13117 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x19
13118 && ((dummy >> 24) & 0xFF) == 0x04)
13119 tmp_type |= DRF_G_FLOAT;
13120 else
13121 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
13122
13123 d = (double) 1.2345;
13124 dummy = 0;
13125 memcpy(&dummy, &d, sizeof(f));
13126 if ((dummy & 0xFF) == 0x8D && /* little endian */
13127 ((dummy >> 8) & 0xFF) == 0x97 && ((dummy >> 16) & 0xFF) == 0x6E
13128 && ((dummy >> 24) & 0xFF) == 0x12)
13129 tmp_type |= DRF_IEEE;
13130 else if ((dummy & 0xFF) == 0x83 && /* big endian */
13131 ((dummy >> 8) & 0xFF) == 0xC0 && ((dummy >> 16) & 0xFF) == 0xF3
13132 && ((dummy >> 24) & 0xFF) == 0x3F)
13133 tmp_type |= DRF_IEEE;
13134 else if ((dummy & 0xFF) == 0x13 &&
13135 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x83
13136 && ((dummy >> 24) & 0xFF) == 0xC0)
13137 tmp_type |= DRF_G_FLOAT;
13138 else if ((dummy & 0xFF) == 0x9E &&
13139 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x18
13140 && ((dummy >> 24) & 0xFF) == 0x04)
13141 cm_msg(MERROR, "rpc_get_option",
13142 "MIDAS cannot handle VAX D FLOAT format. Please compile with the /g_float flag");
13143 else
13144 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
13145
13146 return tmp_type;
13147 }
13148 }
13149}
#define DRI_32
Definition msystem.h:46
#define DRI_16
Definition msystem.h:45
#define DRI_64
Definition msystem.h:47
double d
Definition system.cxx:1313
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_locked_client_connection()

static RPC_CLIENT_CONNECTION * rpc_get_locked_client_connection ( HNDLE  hConn)
static

Definition at line 12845 of file midas.cxx.

12846{
12848 if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12850 if (c && c->connected) {
12852 c->mutex.lock();
12853 if (!c->connected) {
12854 // disconnected while we were waiting for the lock
12855 c->mutex.unlock();
12856 return NULL;
12857 }
12858 return c;
12859 }
12860 }
12862 return NULL;
12863}
Here is the caller graph for this function:

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION * rpc_get_mserver_acception ( void  )

Definition at line 11746 of file midas.cxx.

11747{
11748 return _mserver_acception;
11749}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 13038 of file midas.cxx.

13046{
13048}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13284 of file midas.cxx.

13292{
13293 return _mserver_path.c_str();
13294}
static std::string _mserver_path
Definition midas.cxx:13281
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13317 of file midas.cxx.

13335{
13336 return _client_name;
13337}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 14422 of file midas.cxx.

14422 {
14423 return _opt_tcp_size;
14424}
static int _opt_tcp_size
Definition midas.cxx:11809

◆ rpc_get_timeout()

INT rpc_get_timeout ( HNDLE  hConn)

dox Set RPC option

Parameters
hConnRPC connection handle, -1 for server connection, -2 for rpc connect timeout
itemOne of RPC_Oxxx
valueValue to set
Returns
RPC_SUCCESS Get RPC timeout
Parameters
hConnRPC connection handle, RPC_HNDLE_MSERVER for mserver connection, RPC_HNDLE_CONNECT for rpc connect timeout
Returns
timeout value

Definition at line 13206 of file midas.cxx.

13207{
13208 if (hConn == RPC_HNDLE_MSERVER) {
13210 } else if (hConn == RPC_HNDLE_CONNECT) {
13211 return _rpc_connect_timeout;
13212 } else {
13214 if (c) {
13215 int timeout = c->rpc_timeout;
13216 c->mutex.unlock();
13217 return timeout;
13218 }
13219 }
13220 return 0;
13221}
#define RPC_HNDLE_CONNECT
Definition midas.h:394
#define RPC_HNDLE_MSERVER
Definition midas.h:393
Here is the call graph for this function:

◆ rpc_ieee2vax_double()

void rpc_ieee2vax_double ( double *  var)

Definition at line 11894 of file midas.cxx.

11894 {
11895 unsigned short int i1, i2, i3, i4;
11896
11897 /* swap words */
11898 i1 = *((short int *) (var) + 3);
11899 i2 = *((short int *) (var) + 2);
11900 i3 = *((short int *) (var) + 1);
11901 i4 = *((short int *) (var));
11902
11903 /* correct exponent */
11904 if (i1 != 0)
11905 i1 += 0x20;
11906
11907 *((short int *) (var) + 3) = i4;
11908 *((short int *) (var) + 2) = i3;
11909 *((short int *) (var) + 1) = i2;
11910 *((short int *) (var)) = i1;
11911}
Here is the caller graph for this function:

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float *  var)

Definition at line 11844 of file midas.cxx.

11844 {
11845 unsigned short int lo, hi;
11846
11847 /* swap hi and lo word */
11848 lo = *((short int *) (var) + 1);
11849 hi = *((short int *) (var));
11850
11851 /* correct exponent */
11852 if (lo != 0)
11853 lo += 0x100;
11854
11855 *((short int *) (var) + 1) = hi;
11856 *((short int *) (var)) = lo;
11857}
Here is the caller graph for this function:

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 13016 of file midas.cxx.

13033{
13034 return _server_connection.send_sock != 0;
13035}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 13051 of file midas.cxx.

13062{
13063 return _mserver_acception != NULL;
13064}
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12994 of file midas.cxx.

13011{
13012 return _rpc_is_remote;
13013}
static bool _rpc_is_remote
Definition midas.cxx:11740

◆ rpc_name_tid()

int rpc_name_tid ( const char *  name)

Definition at line 12011 of file midas.cxx.

12012{
12013 for (int i=0; i<TID_LAST; i++) {
12014 if (strcmp(name, tid_name[i]) == 0)
12015 return i;
12016 }
12017
12018 for (int i=0; i<TID_LAST; i++) {
12019 if (strcmp(name, tid_name_old[i]) == 0)
12020 return i;
12021 }
12022
12023 return 0;
12024}
#define TID_LAST
Definition midas.h:354
static const char * tid_name[]
Definition midas.cxx:111
static const char * tid_name_old[]
Definition midas.cxx:89
#define name(x)
Definition midas_macro.h:24
Here is the caller graph for this function:

◆ rpc_new_server_acception()

static RPC_SERVER_ACCEPTION * rpc_new_server_acception ( )
static

Definition at line 11751 of file midas.cxx.

11752{
11753 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11754 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11755 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11756 return _server_acceptions[idx];
11757 }
11758 }
11759
11761
11762 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11763 if (_server_acceptions[idx] == NULL) {
11764 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11765 _server_acceptions[idx] = sa;
11766 return _server_acceptions[idx];
11767 }
11768 }
11769
11770 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11771 _server_acceptions.push_back(sa);
11772
11773 return sa;
11774}
struct rpc_server_acception_struct RPC_SERVER_ACCEPTION
Here is the caller graph for this function:

◆ rpc_register_client()

INT rpc_register_client ( const char *  name,
RPC_LIST list 
)

Register RPC client for standalone mode (without standard midas server)

Parameters
listArray of RPC_LIST structures containing function IDs and parameter definitions. The end of the list must be indicated by a function ID of zero.
nameName of this client
Returns
RPC_SUCCESS

Definition at line 12041 of file midas.cxx.

12041 {
12045
12046 return RPC_SUCCESS;
12047}
RPC_LIST * rpc_get_internal_list(INT flag)
Definition mrpc.cxx:787
INT rpc_register_functions(const RPC_LIST *new_list, RPC_HANDLER func)
Definition midas.cxx:12060
INT rpc_set_name(const char *name)
Definition midas.cxx:13341
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_function()

INT rpc_register_function ( INT  id,
INT(*)(INT, void **)  func 
)

Definition at line 12130 of file midas.cxx.

12149{
12150 std::lock_guard<std::mutex> guard(rpc_list_mutex);
12151
12152 for (size_t i = 0; i < rpc_list.size(); i++) {
12153 if (rpc_list[i].id == id) {
12154 rpc_list[i].dispatch = func;
12155 return RPC_SUCCESS;
12156 }
12157 }
12158
12159 return RPC_INVALID_ID;
12160}
Here is the caller graph for this function:

◆ rpc_register_functions()

INT rpc_register_functions ( const RPC_LIST new_list,
RPC_HANDLER  func 
)

Register a set of RPC functions (both as clients or servers)

Parameters
new_listArray of RPC_LIST structures containing function IDs and parameter definitions. The end of the list must be indicated by a function ID of zero.
funcDefault dispatch function
Returns
RPC_SUCCESS, RPC_NO_MEMORY, RPC_DOUBLE_DEFINED

Definition at line 12060 of file midas.cxx.

12061{
12062 for (int i = 0; new_list[i].id != 0; i++) {
12063 /* check valid ID for user functions */
12064 if (new_list != rpc_get_internal_list(0) &&
12065 new_list != rpc_get_internal_list(1) && (new_list[i].id < RPC_MIN_ID
12066 || new_list[i].id > RPC_MAX_ID)) {
12067 cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID %d", new_list[i].id);
12068 }
12069 }
12070
12071 std::lock_guard<std::mutex> guard(rpc_list_mutex);
12072
12073 /* check double defined functions */
12074 for (int i = 0; new_list[i].id != 0; i++) {
12075 for (size_t j = 0; j < rpc_list.size(); j++) {
12076 if (rpc_list[j].id == new_list[i].id) {
12077 return RPC_DOUBLE_DEFINED;
12078 }
12079 }
12080 }
12081
12082 /* append new functions */
12083 for (int i = 0; new_list[i].id != 0; i++) {
12084 RPC_LIST e = new_list[i];
12085
12086 /* set default dispatcher */
12087 if (e.dispatch == NULL) {
12088 e.dispatch = func;
12089 }
12090
12091 rpc_list.push_back(e);
12092 }
12093
12094 return RPC_SUCCESS;
12095}
#define RPC_DOUBLE_DEFINED
Definition midas.h:710
#define RPC_MIN_ID
Definition midas.h:1542
#define RPC_MAX_ID
Definition midas.h:1543
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_listener()

INT rpc_register_listener ( int  port,
RPC_HANDLER  func,
int *  plsock,
int *  pport 
)

Definition at line 15127 of file midas.cxx.

15150{
15151 /* register system functions: RPC_ID_EXIT, RPC_ID_SHUTDOWN, RPC_ID_WATCHDOG */
15153
15154 /* create a socket for listening */
15155 int lsock = 0;
15156 int lport = 0;
15157 std::string errmsg;
15158
15159 int status = ss_socket_listen_tcp(!disable_bind_rpc_to_localhost, port, &lsock, &lport, &errmsg);
15160
15161 if (status != SS_SUCCESS) {
15162 cm_msg(MERROR, "rpc_register_server", "cannot listen to tcp port %d: %s", port, errmsg.c_str());
15163 return RPC_NET_ERROR;
15164 }
15165
15166 /* set close-on-exec flag to prevent child mserver processes from inheriting the listen socket */
15167#if defined(F_SETFD) && defined(FD_CLOEXEC)
15168 status = fcntl(lsock, F_SETFD, fcntl(lsock, F_GETFD) | FD_CLOEXEC);
15169 if (status < 0) {
15170 cm_msg(MERROR, "rpc_register_server", "fcntl(F_SETFD, FD_CLOEXEC) failed, errno %d (%s)", errno, strerror(errno));
15171 return RPC_NET_ERROR;
15172 }
15173#endif
15174
15175 /* return port wich OS has choosen */
15176 if (pport) {
15177 *pport = lport;
15178 }
15179
15180 if (plsock)
15181 *plsock = lsock;
15182
15183 //printf("rpc_register_server: requested port %d, actual port %d, socket %d\n", port, *pport, *plsock);
15184
15185 return RPC_SUCCESS;
15186}
INT ss_socket_listen_tcp(bool listen_localhost, int tcp_port, int *sockp, int *tcp_port_p, std::string *error_msg_p)
Definition system.cxx:5141
static int disable_bind_rpc_to_localhost
Definition midas.cxx:237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_server()

INT rpc_register_server ( int  port,
int *  plsock,
int *  pport 
)

Definition at line 15086 of file midas.cxx.

15108{
15109 int status;
15110 int lsock;
15111
15112 status = rpc_register_listener(port, NULL, &lsock, pport);
15113 if (status != RPC_SUCCESS)
15114 return status;
15115
15117 if (status != SS_SUCCESS)
15118 return status;
15119
15120 if (plsock)
15121 *plsock = lsock;
15122
15123 return RPC_SUCCESS;
15124}
INT ss_suspend_set_client_listener(int listen_socket)
Definition system.cxx:4363
INT rpc_register_listener(int port, RPC_HANDLER func, int *plsock, int *pport)
Definition midas.cxx:15127
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_send_event()

INT rpc_send_event ( INT  buffer_handle,
const EVENT_HEADER pevent,
int  unused,
INT  async_flag,
INT  mode 
)

dox Fast send_event routine which bypasses the RPC layer and sends the event directly at the TCP level.

Parameters
buffer_handleHandle of the buffer to send the event to. Must be obtained via bm_open_buffer.
sourceAddress of the event to send. It must have a proper event header.
buf_sizeSize of event in bytes with header.
async_flagBM_WAIT / BM_NO_WAIT flag. In BM_NO_WAIT mode, the function returns immediately if it cannot send the event over the network. In BM_WAIT mode, it waits until the packet is sent (blocking).
modeDetermines in which mode the event is sent. If zero, use RPC socket, if one, use special event socket to bypass RPC layer on the server side.
Returns
BM_INVALID_PARAM, BM_ASYNC_RETURN, RPC_SUCCESS, RPC_NET_ERROR, RPC_NO_CONNECTION, RPC_EXCEED_BUFFER

Definition at line 14451 of file midas.cxx.

14452{
14453 if (rpc_is_remote()) {
14454 return rpc_send_event1(buffer_handle, pevent);
14455 } else {
14456 return bm_send_event(buffer_handle, pevent, unused, async_flag);
14457 }
14458}
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition midas.cxx:9791
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition midas.cxx:14469
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_send_event1()

INT rpc_send_event1 ( INT  buffer_handle,
const EVENT_HEADER pevent 
)

Send event to mserver using the event socket connection, bypassing the RPC layer

Parameters
buffer_handleHandle of the buffer to send the event to. Must be obtained via bm_open_buffer.
eventPointer to event header
Returns
RPC_SUCCESS, RPC_NET_ERROR, RPC_NO_CONNECTION

Definition at line 14469 of file midas.cxx.

14470{
14471 const size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
14472 return rpc_send_event_sg(buffer_handle, 1, (char**)&pevent, &event_size);
14473}
INT rpc_send_event_sg(INT buffer_handle, int sg_n, const char *const sg_ptr[], const size_t sg_len[])
Definition midas.cxx:14475
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_send_event_sg()

INT rpc_send_event_sg ( INT  buffer_handle,
int  sg_n,
const char *const  sg_ptr[],
const size_t  sg_len[] 
)

Definition at line 14475 of file midas.cxx.

14476{
14477 if (sg_n < 1) {
14478 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_n %d", sg_n);
14479 return BM_INVALID_SIZE;
14480 }
14481
14482 if (sg_ptr[0] == NULL) {
14483 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_ptr[0] is NULL");
14484 return BM_INVALID_SIZE;
14485 }
14486
14487 if (sg_len[0] < sizeof(EVENT_HEADER)) {
14488 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_len[0] value %d is smaller than event header size %d", (int)sg_len[0], (int)sizeof(EVENT_HEADER));
14489 return BM_INVALID_SIZE;
14490 }
14491
14492 const EVENT_HEADER* pevent = (const EVENT_HEADER*)sg_ptr[0];
14493
14494 const DWORD MAX_DATA_SIZE = (0x7FFFFFF0 - 16); // event size computations are not 32-bit clean, limit event size to 2GB. K.O.
14495 const DWORD data_size = pevent->data_size; // 32-bit unsigned value
14496
14497 if (data_size == 0) {
14498 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size zero");
14499 return BM_INVALID_SIZE;
14500 }
14501
14502 if (data_size > MAX_DATA_SIZE) {
14503 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size %d (0x%x) maximum is %d (0x%x)", data_size, data_size, MAX_DATA_SIZE, MAX_DATA_SIZE);
14504 return BM_INVALID_SIZE;
14505 }
14506
14507 const size_t event_size = sizeof(EVENT_HEADER) + data_size;
14508 const size_t total_size = ALIGN8(event_size);
14509
14510 size_t count = 0;
14511 for (int i=0; i<sg_n; i++) {
14512 count += sg_len[i];
14513 }
14514
14515 if (count != event_size) {
14516 cm_msg(MERROR, "rpc_send_event_sg", "data size mismatch: event data_size %d, event_size %d not same as sum of sg_len %d", (int)data_size, (int)event_size, (int)count);
14517 return BM_INVALID_SIZE;
14518 }
14519
14520 // protect non-atomic access to _server_connection.event_sock. K.O.
14521
14522 std::lock_guard<std::mutex> guard(_server_connection.event_sock_mutex);
14523
14524 //printf("rpc_send_event_sg: pevent %p, event_id 0x%04x, serial 0x%08x, data_size %d, event_size %d, total_size %d\n", pevent, pevent->event_id, pevent->serial_number, (int)data_size, (int)event_size, (int)total_size);
14525
14526 if (_server_connection.event_sock == 0) {
14527 return RPC_NO_CONNECTION;
14528 }
14529
14530 //
14531 // event socket wire protocol: (see also rpc_server_receive_event() and recv_event_server_realloc())
14532 //
14533 // 4 bytes of buffer handle
14534 // 16 bytes of event header, includes data_size
14535 // ALIGN8(data_size) bytes of event data
14536 //
14537
14538 int status;
14539
14540 /* send buffer handle */
14541
14542 assert(sizeof(DWORD) == 4);
14543 DWORD bh_buf = buffer_handle;
14544
14545 status = ss_write_tcp(_server_connection.event_sock, (const char *) &bh_buf, sizeof(DWORD));
14546 if (status != SS_SUCCESS) {
14548 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(buffer handle) failed, event socket is now closed");
14549 return RPC_NET_ERROR;
14550 }
14551
14552 /* send data */
14553
14554 for (int i=0; i<sg_n; i++) {
14555 status = ss_write_tcp(_server_connection.event_sock, sg_ptr[i], sg_len[i]);
14556 if (status != SS_SUCCESS) {
14558 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(event data) failed, event socket is now closed");
14559 return RPC_NET_ERROR;
14560 }
14561 }
14562
14563 /* send padding */
14564
14565 if (count < total_size) {
14566 char padding[8] = { 0,0,0,0,0,0,0,0 };
14567 size_t padlen = total_size - count;
14568 assert(padlen < 8);
14570 if (status != SS_SUCCESS) {
14572 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(padding) failed, event socket is now closed");
14573 return RPC_NET_ERROR;
14574 }
14575 }
14576
14577 return RPC_SUCCESS;
14578}
#define BM_INVALID_SIZE
Definition midas.h:624
INT ss_write_tcp(int sock, const char *buffer, size_t buffer_size)
Definition system.cxx:5431
double count
Definition mdump.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_accept()

INT rpc_server_accept ( int  lsock)

Definition at line 16813 of file midas.cxx.

16834{
16835 INT i;
16836 INT sock;
16837 char version[NAME_LENGTH], v1[32];
16838 char experiment[NAME_LENGTH];
16839 INT port1, port2, port3;
16840 char *ptr;
16841 char net_buffer[256];
16842 struct linger ling;
16843
16844 static struct callback_addr callback;
16845
16846 if (lsock > 0) {
16847 sock = accept(lsock, NULL, NULL);
16848
16849 if (sock == -1)
16850 return RPC_NET_ERROR;
16851 } else {
16852 /* lsock is stdin -> already connected from inetd */
16853
16854 sock = lsock;
16855 }
16856
16857 /* check access control list */
16860
16861 if (status != RPC_SUCCESS) {
16862 ss_socket_close(&sock);
16863 return RPC_NET_ERROR;
16864 }
16865 }
16866
16867 /* receive string with timeout */
16868 i = recv_string(sock, net_buffer, 256, 10000);
16869 rpc_debug_printf("Received command: %s", net_buffer);
16870
16871 if (i > 0) {
16872 char command = (char) toupper(net_buffer[0]);
16873
16874 //printf("rpc_server_accept: command [%c]\n", command);
16875
16876 switch (command) {
16877 case 'S': {
16878
16879 /*----------- shutdown listener ----------------------*/
16880 ss_socket_close(&sock);
16881 return RPC_SHUTDOWN;
16882 }
16883 case 'I': {
16884
16885 /*----------- return available experiments -----------*/
16886#ifdef LOCAL_ROUTINES
16887 exptab_struct exptab;
16888 cm_read_exptab(&exptab); // thread safe!
16889 for (unsigned i=0; i<exptab.exptab.size(); i++) {
16890 rpc_debug_printf("Return experiment: %s", exptab.exptab[i].name.c_str());
16891 const char* str = exptab.exptab[i].name.c_str();
16892 send(sock, str, strlen(str) + 1, 0);
16893 }
16894 send(sock, "", 1, 0);
16895#endif
16896 ss_socket_close(&sock);
16897 break;
16898 }
16899 case 'C': {
16900
16901 /*----------- connect to experiment -----------*/
16902
16903 /* get callback information */
16904 callback.experiment[0] = 0;
16905 port1 = port2 = version[0] = 0;
16906
16907 //printf("rpc_server_accept: net buffer \'%s\'\n", net_buffer);
16908
16909 /* parse string in format "C port1 port2 port3 version expt" */
16910 /* example: C 51046 45838 56832 2.0.0 alpha */
16911
16912 port1 = strtoul(net_buffer + 2, &ptr, 0);
16913 port2 = strtoul(ptr, &ptr, 0);
16914 port3 = strtoul(ptr, &ptr, 0);
16915
16916 while (*ptr == ' ')
16917 ptr++;
16918
16919 i = 0;
16920 for (; *ptr != 0 && *ptr != ' ' && i < (int) sizeof(version) - 1;)
16921 version[i++] = *ptr++;
16922
16923 // ensure that we do not overwrite buffer "version"
16924 assert(i < (int) sizeof(version));
16925 version[i] = 0;
16926
16927 // skip wjatever is left from the "version" string
16928 for (; *ptr != 0 && *ptr != ' ';)
16929 ptr++;
16930
16931 while (*ptr == ' ')
16932 ptr++;
16933
16934 i = 0;
16935 for (; *ptr != 0 && *ptr != ' ' && *ptr != '\n' && *ptr != '\r' && i < (int) sizeof(experiment) - 1;)
16936 experiment[i++] = *ptr++;
16937
16938 // ensure that we do not overwrite buffer "experiment"
16939 assert(i < (int) sizeof(experiment));
16940 experiment[i] = 0;
16941
16943
16944 /* print warning if version patch level doesn't agree */
16945 mstrlcpy(v1, version, sizeof(v1));
16946 if (strchr(v1, '.'))
16947 if (strchr(strchr(v1, '.') + 1, '.'))
16948 *strchr(strchr(v1, '.') + 1, '.') = 0;
16949
16950 char str[100];
16951 mstrlcpy(str, cm_get_version(), sizeof(str));
16952 if (strchr(str, '.'))
16953 if (strchr(strchr(str, '.') + 1, '.'))
16954 *strchr(strchr(str, '.') + 1, '.') = 0;
16955
16956 if (strcmp(v1, str) != 0) {
16957 cm_msg(MERROR, "rpc_server_accept", "client MIDAS version %s differs from local version %s", version, cm_get_version());
16958 cm_msg(MERROR, "rpc_server_accept", "received string: %s", net_buffer + 2);
16959 }
16960
16961 callback.host_port1 = (short) port1;
16962 callback.host_port2 = (short) port2;
16963 callback.host_port3 = (short) port3;
16965
16967
16968 if (status != SS_SUCCESS) {
16969 ss_socket_close(&sock);
16970 break;
16971 }
16972
16973#ifdef LOCAL_ROUTINES
16974 /* update experiment definition */
16975 exptab_struct exptab;
16976 cm_read_exptab(&exptab); // thread safe!
16977
16978 unsigned idx = 0;
16979 bool found = false;
16980 /* lookup experiment */
16981 if (equal_ustring(callback.experiment.c_str(), "Default")) {
16982 found = true;
16983 idx = 0;
16984 } else {
16985 for (idx = 0; idx < exptab.exptab.size(); idx++) {
16986 if (exptab.exptab[idx].name == callback.experiment) {
16987 if (ss_dir_exist(exptab.exptab[idx].directory.c_str())) {
16988 found = true;
16989 break;
16990 }
16991 }
16992 }
16993 }
16994
16995 if (!found) {
16996 cm_msg(MERROR, "rpc_server_accept", "experiment \'%s\' not defined in exptab file \'%s\'", callback.experiment.c_str(), exptab.filename.c_str());
16997
16998 send(sock, "2", 2, 0); /* 2 means exp. not found */
16999 ss_socket_close(&sock);
17000 break;
17001 }
17002
17003 callback.directory = exptab.exptab[idx].directory;
17004 callback.user = exptab.exptab[idx].user;
17005
17006 /* create a new process */
17007 char host_port1_str[30], host_port2_str[30], host_port3_str[30];
17008 char debug_str[30];
17009
17010 sprintf(host_port1_str, "%d", callback.host_port1);
17011 sprintf(host_port2_str, "%d", callback.host_port2);
17012 sprintf(host_port3_str, "%d", callback.host_port3);
17013 sprintf(debug_str, "%d", callback.debug);
17014
17015 const char *mserver_path = rpc_get_mserver_path();
17016
17017 const char *argv[10];
17018 argv[0] = mserver_path;
17019 argv[1] = callback.host_name.c_str();
17020 argv[2] = host_port1_str;
17021 argv[3] = host_port2_str;
17022 argv[4] = host_port3_str;
17023 argv[5] = debug_str;
17024 argv[6] = callback.experiment.c_str();
17025 argv[7] = callback.directory.c_str();
17026 argv[8] = callback.user.c_str();
17027 argv[9] = NULL;
17028
17029 rpc_debug_printf("Spawn: %s %s %s %s %s %s %s %s %s %s",
17030 argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8],
17031 argv[9]);
17032
17033 status = ss_spawnv(P_NOWAIT, mserver_path, argv);
17034
17035 if (status != SS_SUCCESS) {
17036 rpc_debug_printf("Cannot spawn subprocess: %s\n", strerror(errno));
17037
17038 sprintf(str, "3"); /* 3 means cannot spawn subprocess */
17039 send(sock, str, strlen(str) + 1, 0);
17040 ss_socket_close(&sock);
17041 break;
17042 }
17043
17044 sprintf(str, "1 %s", cm_get_version()); /* 1 means ok */
17045 send(sock, str, strlen(str) + 1, 0);
17046#endif // LOCAL_ROUTINES
17047 ss_socket_close(&sock);
17048
17049 break;
17050 }
17051 default: {
17052 cm_msg(MERROR, "rpc_server_accept", "received unknown command '%c' code %d", command, command);
17053 ss_socket_close(&sock);
17054 break;
17055 }
17056 }
17057 } else { /* if i>0 */
17058
17059 /* lingering needed for PCTCP */
17060 ling.l_onoff = 1;
17061 ling.l_linger = 0;
17062 setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17063 ss_socket_close(&sock);
17064 }
17065
17066 return RPC_SUCCESS;
17067}
INT cm_read_exptab(exptab_struct *exptab)
Definition midas.cxx:1664
INT ss_socket_get_peer_name(int sock, std::string *hostp, int *portp)
Definition system.cxx:5325
int ss_dir_exist(const char *path)
Definition system.cxx:7271
INT ss_spawnv(INT mode, const char *cmdname, const char *const argv[])
Definition system.cxx:1702
const char * rpc_get_mserver_path()
Definition midas.cxx:13284
#define NAME_LENGTH
Definition midas.h:272
struct callback_addr callback
Definition mserver.cxx:22
unsigned short host_port1
Definition msystem.h:319
std::string user
Definition msystem.h:325
unsigned short host_port2
Definition msystem.h:320
std::string experiment
Definition msystem.h:323
unsigned short host_port3
Definition msystem.h:321
std::string directory
Definition msystem.h:324
std::string host_name
Definition msystem.h:318
std::string filename
Definition midas.cxx:1651
std::vector< exptab_entry > exptab
Definition midas.cxx:1652
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_callback()

INT rpc_server_callback ( struct callback_addr pcallback)

Definition at line 17174 of file midas.cxx.

17193{
17194 INT status;
17195 int recv_sock, send_sock, event_sock;
17196 char str[100];
17197 std::string client_program;
17198 INT client_hw_type, hw_type;
17199 INT convert_flags;
17200 char net_buffer[256];
17201 char *p;
17202 int flag;
17203
17204 /* copy callback information */
17205 struct callback_addr callback = *pcallback;
17206 //idx = callback.index;
17207
17208 std::string errmsg;
17209
17210 /* create new sockets for TCP */
17211 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port1, &recv_sock, &errmsg);
17212
17213 if (status != SS_SUCCESS) {
17214 cm_msg(MERROR, "rpc_server_callback", "cannot connect receive socket, host \"%s\", port %d: %s", callback.host_name.c_str(), callback.host_port1, errmsg.c_str());
17215 ss_socket_close(&recv_sock);
17216 //ss_socket_close(&send_sock);
17217 //ss_socket_close(&event_sock);
17218 return RPC_NET_ERROR;
17219 }
17220
17221 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port2, &send_sock, &errmsg);
17222
17223 if (status != SS_SUCCESS) {
17224 cm_msg(MERROR, "rpc_server_callback", "cannot connect send socket, host \"%s\", port %d: %s", callback.host_name.c_str(), callback.host_port2, errmsg.c_str());
17225 ss_socket_close(&recv_sock);
17226 ss_socket_close(&send_sock);
17227 //ss_socket_close(&event_sock);
17228 return RPC_NET_ERROR;
17229 }
17230
17231 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port3, &event_sock, &errmsg);
17232
17233 if (status != SS_SUCCESS) {
17234 cm_msg(MERROR, "rpc_server_callback", "cannot connect event socket, host \"%s\", port %d: %s", callback.host_name.c_str(), callback.host_port2, errmsg.c_str());
17235 ss_socket_close(&recv_sock);
17236 ss_socket_close(&send_sock);
17237 ss_socket_close(&event_sock);
17238 return RPC_NET_ERROR;
17239 }
17240#ifndef OS_ULTRIX /* crashes ULTRIX... */
17241 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
17242 flag = 2 * 1024 * 1024;
17243 status = setsockopt(event_sock, SOL_SOCKET, SO_RCVBUF, (char *) &flag, sizeof(INT));
17244 if (status != 0)
17245 cm_msg(MERROR, "rpc_server_callback", "cannot setsockopt(SOL_SOCKET, SO_RCVBUF), errno %d (%s)", errno,
17246 strerror(errno));
17247#endif
17248
17249 if (recv_string(recv_sock, net_buffer, 256, _rpc_connect_timeout) <= 0) {
17250 cm_msg(MERROR, "rpc_server_callback", "timeout on receive remote computer info");
17251 ss_socket_close(&recv_sock);
17252 ss_socket_close(&send_sock);
17253 ss_socket_close(&event_sock);
17254 return RPC_NET_ERROR;
17255 }
17256 //printf("rpc_server_callback: \'%s\'\n", net_buffer);
17257
17258 /* get remote computer info */
17259 client_hw_type = strtoul(net_buffer, &p, 0);
17260
17261 while (*p == ' ')
17262 p++;
17263
17264 client_program = p;
17265
17266 //printf("hw type %d, name \'%s\'\n", client_hw_type, client_program);
17267
17268 std::string host_name;
17269
17270 status = ss_socket_get_peer_name(recv_sock, &host_name, NULL);
17271
17272 if (status != SS_SUCCESS)
17273 host_name = "unknown";
17274
17275 //printf("rpc_server_callback: mserver acception\n");
17276
17278
17279 /* save information in _server_acception structure */
17280 sa->recv_sock = recv_sock;
17281 sa->send_sock = send_sock;
17282 sa->event_sock = event_sock;
17283 sa->remote_hw_type = client_hw_type;
17284 sa->host_name = host_name;
17285 sa->prog_name = client_program;
17287 sa->watchdog_timeout = 0;
17288 sa->is_mserver = TRUE;
17289
17290 assert(_mserver_acception == NULL);
17291
17292 _mserver_acception = sa;
17293
17294 //printf("rpc_server_callback: _mserver_acception %p\n", _mserver_acception);
17295
17296 /* send my own computer id */
17297 hw_type = rpc_get_hw_type();
17298 sprintf(str, "%d", hw_type);
17299 send(recv_sock, str, strlen(str) + 1, 0);
17300
17301 rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
17302 sa->convert_flags = convert_flags;
17303
17305
17306 if (rpc_is_mserver()) {
17307 rpc_debug_printf("Connection to %s:%s established\n", sa->host_name.c_str(), sa->prog_name.c_str());
17308 }
17309
17310 return RPC_SUCCESS;
17311}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_connect()

INT rpc_server_connect ( const char *  host_name,
const char *  exp_name 
)

Definition at line 12614 of file midas.cxx.

12642{
12643 INT i, status;
12644 INT remote_hw_type, hw_type;
12645 char str[200], version[32], v1[32];
12646 fd_set readfds;
12647 struct timeval timeout;
12648 int port = MIDAS_TCP_PORT;
12649 char *s;
12650
12651#ifdef OS_WINNT
12652 {
12653 WSADATA WSAData;
12654
12655 /* Start windows sockets */
12656 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
12657 return RPC_NET_ERROR;
12658 }
12659#endif
12660
12661 /* check if local connection */
12662 if (host_name[0] == 0)
12663 return RPC_SUCCESS;
12664
12665 /* register system functions */
12667
12668 /* check if cm_connect_experiment was called */
12669 if (_client_name.length() == 0) {
12670 cm_msg(MERROR, "rpc_server_connect", "cm_connect_experiment/rpc_set_name not called");
12671 return RPC_NOT_REGISTERED;
12672 }
12673
12674 /* check if connection already exists */
12676 return RPC_SUCCESS;
12677
12681
12682 bool listen_localhost = false;
12683
12684 if (strcmp(host_name, "localhost") == 0)
12685 listen_localhost = true;
12686
12687 int lsock1, lport1;
12688 int lsock2, lport2;
12689 int lsock3, lport3;
12690
12691 std::string errmsg;
12692
12693 status = ss_socket_listen_tcp(listen_localhost, 0, &lsock1, &lport1, &errmsg);
12694
12695 if (status != SS_SUCCESS) {
12696 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12697 return RPC_NET_ERROR;
12698 }
12699
12700 status = ss_socket_listen_tcp(listen_localhost, 0, &lsock2, &lport2, &errmsg);
12701
12702 if (status != SS_SUCCESS) {
12703 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12704 return RPC_NET_ERROR;
12705 }
12706
12707 status = ss_socket_listen_tcp(listen_localhost, 0, &lsock3, &lport3, &errmsg);
12708
12709 if (status != SS_SUCCESS) {
12710 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12711 return RPC_NET_ERROR;
12712 }
12713
12714 /* extract port number from host_name */
12715 mstrlcpy(str, host_name, sizeof(str));
12716 s = strchr(str, ':');
12717 if (s) {
12718 *s = 0;
12719 port = strtoul(s + 1, NULL, 0);
12720 }
12721
12722 int sock;
12723
12724 status = ss_socket_connect_tcp(str, port, &sock, &errmsg);
12725
12726 if (status != SS_SUCCESS) {
12727 cm_msg(MERROR, "rpc_server_connect", "cannot connect to mserver on host \"%s\" port %d: %s", str, port, errmsg.c_str());
12728 return RPC_NET_ERROR;
12729 }
12730
12731 /* connect to experiment */
12732 if (exp_name[0] == 0)
12733 sprintf(str, "C %d %d %d %s Default", lport1, lport2, lport3, cm_get_version());
12734 else
12735 sprintf(str, "C %d %d %d %s %s", lport1, lport2, lport3, cm_get_version(), exp_name);
12736
12737 send(sock, str, strlen(str) + 1, 0);
12738 i = recv_string(sock, str, sizeof(str), _rpc_connect_timeout);
12739 ss_socket_close(&sock);
12740 if (i <= 0) {
12741 cm_msg(MERROR, "rpc_server_connect", "timeout on receive status from server");
12742 return RPC_NET_ERROR;
12743 }
12744
12745 status = version[0] = 0;
12746 sscanf(str, "%d %s", &status, version);
12747
12748 if (status == 2) {
12749/* message "undefined experiment" should be displayed by application */
12750 return CM_UNDEF_EXP;
12751 }
12752
12753 /* print warning if version patch level doesn't agree */
12754 strcpy(v1, version);
12755 if (strchr(v1, '.'))
12756 if (strchr(strchr(v1, '.') + 1, '.'))
12757 *strchr(strchr(v1, '.') + 1, '.') = 0;
12758
12759 strcpy(str, cm_get_version());
12760 if (strchr(str, '.'))
12761 if (strchr(strchr(str, '.') + 1, '.'))
12762 *strchr(strchr(str, '.') + 1, '.') = 0;
12763
12764 if (strcmp(v1, str) != 0) {
12765 cm_msg(MERROR, "rpc_server_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", version,
12766 cm_get_version());
12767 }
12768
12769 /* wait for callback on send and recv socket with timeout */
12770 FD_ZERO(&readfds);
12771 FD_SET(lsock1, &readfds);
12772 FD_SET(lsock2, &readfds);
12773 FD_SET(lsock3, &readfds);
12774
12775 timeout.tv_sec = _rpc_connect_timeout / 1000;
12776 timeout.tv_usec = 0;
12777
12778 do {
12779 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12780
12781 /* if an alarm signal was cought, restart select with reduced timeout */
12782 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
12783 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
12784
12785 } while (status == -1); /* dont return if an alarm signal was cought */
12786
12787 if (!FD_ISSET(lsock1, &readfds)) {
12788 cm_msg(MERROR, "rpc_server_connect", "mserver subprocess could not be started (check path)");
12789 ss_socket_close(&lsock1);
12790 ss_socket_close(&lsock2);
12791 ss_socket_close(&lsock3);
12792 return RPC_NET_ERROR;
12793 }
12794
12795 _server_connection.send_sock = accept(lsock1, NULL, NULL);
12796 _server_connection.recv_sock = accept(lsock2, NULL, NULL);
12797 _server_connection.event_sock = accept(lsock3, NULL, NULL);
12798
12800 cm_msg(MERROR, "rpc_server_connect", "accept() failed");
12801 return RPC_NET_ERROR;
12802 }
12803
12804 ss_socket_close(&lsock1);
12805 ss_socket_close(&lsock2);
12806 ss_socket_close(&lsock3);
12807
12808 /* set TCP_NODELAY option for better performance */
12809 int flag = 1;
12810 setsockopt(_server_connection.send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
12811 setsockopt(_server_connection.event_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
12812
12813 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
12814 flag = 2 * 1024 * 1024;
12815 status = setsockopt(_server_connection.event_sock, SOL_SOCKET, SO_SNDBUF, (char *) &flag, sizeof(flag));
12816 if (status != 0)
12817 cm_msg(MERROR, "rpc_server_connect", "cannot setsockopt(SOL_SOCKET, SO_SNDBUF), errno %d (%s)", errno, strerror(errno));
12818
12819 /* send local computer info */
12820 std::string local_prog_name = rpc_get_name();
12821 hw_type = rpc_get_hw_type();
12822 sprintf(str, "%d %s", hw_type, local_prog_name.c_str());
12823
12824 send(_server_connection.send_sock, str, strlen(str) + 1, 0);
12825
12826 /* receive remote computer info */
12828 if (i <= 0) {
12829 cm_msg(MERROR, "rpc_server_connect", "timeout on receive remote computer info");
12830 return RPC_NET_ERROR;
12831 }
12832
12833 sscanf(str, "%d", &remote_hw_type);
12834 _server_connection.remote_hw_type = remote_hw_type;
12835
12837
12838 _rpc_is_remote = true;
12839
12840 return RPC_SUCCESS;
12841}
#define CM_UNDEF_EXP
Definition midas.h:586
INT ss_suspend_set_client_connection(RPC_SERVER_CONNECTION *connection)
Definition system.cxx:4370
char exp_name[NAME_LENGTH]
Definition mana.cxx:243
#define MIDAS_TCP_PORT
Definition midas.h:283
#define WATCHDOG_INTERVAL
Definition midas.h:288
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_disconnect()

INT rpc_server_disconnect ( void  )

Definition at line 12938 of file midas.cxx.

12958{
12959 static int rpc_server_disconnect_recursion_level = 0;
12960
12961 if (rpc_server_disconnect_recursion_level)
12962 return RPC_SUCCESS;
12963
12964 rpc_server_disconnect_recursion_level = 1;
12965
12966 /* flush remaining events */
12968
12969 /* notify server about exit */
12970 if (rpc_is_connected()) {
12972 }
12973
12974 /* close sockets */
12981
12983
12984 /* remove semaphore */
12985 if (_mutex_rpc)
12987 _mutex_rpc = NULL;
12988
12989 rpc_server_disconnect_recursion_level = 0;
12990 return RPC_SUCCESS;
12991}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3290
bool rpc_is_connected(void)
Definition midas.cxx:13016
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:14217
INT rpc_flush_event()
Definition midas.cxx:14588
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_loop()

INT rpc_server_loop ( void  )

Definition at line 17315 of file midas.cxx.

17323{
17324 while (1) {
17325 int status = ss_suspend(1000, 0);
17326
17327 if (status == SS_ABORT || status == SS_EXIT)
17328 break;
17329
17331 break;
17332
17333 /* check alarms, etc */
17335
17337 }
17338
17339 return RPC_SUCCESS;
17340}
INT rpc_check_channels(void)
Definition midas.cxx:17756
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_receive_event()

INT rpc_server_receive_event ( int  idx,
RPC_SERVER_ACCEPTION sa,
int  timeout_msec 
)

Definition at line 17483 of file midas.cxx.

17497{
17498 int status = 0;
17499
17500 DWORD start_time = ss_millitime();
17501
17502 //
17503 // THIS IS NOT THREAD SAFE!!!
17504 //
17505 // IT IS ONLY USED BY THE MSERVER
17506 // MSERVER IS SINGLE-THREADED!!!
17507 //
17508
17509 static char *xbuf = NULL;
17510 static int xbufsize = 0;
17511 static bool xbufempty = true;
17512
17513 // short cut
17514 if (sa == NULL && xbufempty)
17515 return RPC_SUCCESS;
17516
17517 static bool recurse = false;
17518
17519 if (recurse) {
17520 cm_msg(MERROR, "rpc_server_receive_event", "internal error: called recursively");
17521 // do not do anything if we are called recursively
17522 // via recursive ss_suspend() or otherwise. K.O.
17523 if (xbufempty)
17524 return RPC_SUCCESS;
17525 else
17526 return BM_ASYNC_RETURN;
17527 }
17528
17529 recurse = true;
17530
17531 do {
17532 if (xbufempty && sa) {
17533 int n_received = recv_event_server_realloc(idx, sa, &xbuf, &xbufsize);
17534
17535 if (n_received < 0) {
17536 status = SS_ABORT;
17537 cm_msg(MERROR, "rpc_server_receive_event", "recv_event_server_realloc() returned %d, abort", n_received);
17538 goto error;
17539 }
17540
17541 if (n_received == 0) {
17542 // no more data in the tcp socket
17543 recurse = false;
17544 return RPC_SUCCESS;
17545 }
17546
17547 xbufempty = false;
17548 }
17549
17550 if (xbufempty) {
17551 // no event in xbuf buffer
17552 recurse = false;
17553 return RPC_SUCCESS;
17554 }
17555
17556 /* send event to buffer */
17557 INT *pbh = (INT *) xbuf;
17558 EVENT_HEADER *pevent = (EVENT_HEADER *) (pbh + 1);
17559
17560 status = bm_send_event(*pbh, pevent, 0, timeout_msec);
17561
17562 //printf("rpc_server_receiv: buffer_handle %d, event_id 0x%04x, serial 0x%08x, data_size %d, status %d\n", *pbh, pevent->event_id, pevent->serial_number, pevent->data_size, status);
17563
17564 if (status == SS_ABORT) {
17565 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d (SS_ABORT), abort", status);
17566 goto error;
17567 }
17568
17569 if (status == BM_ASYNC_RETURN) {
17570 //cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, event buffer is full", status);
17571 recurse = false;
17572 return status;
17573 }
17574
17575 if (status != BM_SUCCESS) {
17576 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, mserver dropped this event", status);
17577 }
17578
17579 xbufempty = true;
17580
17581 /* repeat for maximum 0.5 sec */
17582 } while (ss_millitime() - start_time < 500);
17583
17584 recurse = false;
17585 return RPC_SUCCESS;
17586
17587 error:
17588
17589 {
17590 char str[80];
17591 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
17592 if (strchr(str, '.'))
17593 *strchr(str, '.') = 0;
17594 cm_msg(MTALK, "rpc_server_receive_event", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
17595 }
17596
17597 //exit:
17598
17600
17601 /* disconnect from experiment as MIDAS server */
17602 if (rpc_is_mserver()) {
17603 HNDLE hDB, hKey;
17604
17606
17607 /* only disconnect from experiment if previously connected.
17608 Necessary for pure RPC servers (RPC_SRVR) */
17609 if (hDB) {
17613
17615
17617 }
17618 }
17619
17620 bool is_mserver = sa->is_mserver;
17621
17622 sa->close();
17623
17624 /* signal caller a shutdonw */
17625 if (status == RPC_SHUTDOWN)
17626 return status;
17627
17628 /* only the mserver should stop on server connection closure */
17629 if (!is_mserver) {
17630 return SS_SUCCESS;
17631 }
17632
17633 return status;
17634}
INT bm_close_all_buffers(void)
Definition midas.cxx:7317
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3083
INT cm_delete_client_info(HNDLE hDB, INT pid)
Definition midas.cxx:1902
INT cm_set_experiment_database(HNDLE hDB, HNDLE hKeyClient)
Definition midas.cxx:3011
#define MTALK
Definition midas.h:564
INT db_close_all_databases(void)
Definition odb.cxx:2893
static int recv_event_server_realloc(INT idx, RPC_SERVER_ACCEPTION *psa, char **pbuffer, int *pbuffer_size)
Definition midas.cxx:14935
INT rpc_deregister_functions()
Definition midas.cxx:12103
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_receive_rpc()

INT rpc_server_receive_rpc ( RPC_SERVER_ACCEPTION sa)

Definition at line 17343 of file midas.cxx.

17358{
17359 int status = 0;
17360 int remaining = 0;
17361
17362 char *buf = NULL;
17363 int bufsize = 0;
17364
17365 do {
17366 int n_received = recv_net_command_realloc(sa, &buf, &bufsize, &remaining);
17367
17368 if (n_received <= 0) {
17369 status = SS_ABORT;
17370 cm_msg(MERROR, "rpc_server_receive_rpc", "recv_net_command() returned %d", n_received);
17371 goto error;
17372 }
17373
17374 /* extract pointer array to parameters */
17375 NET_COMMAND nc_in;
17376
17377 memcpy(&nc_in, buf, sizeof(nc_in));
17378
17379 /* convert header format (byte swapping) */
17380 if (sa->convert_flags) {
17383 }
17384
17385 int routine_id = nc_in.header.routine_id & ~RPC_NO_REPLY;
17386
17387 RPC_LIST rpc_entry;
17388 bool rpc_cxx = false;
17389
17390 status = rpc_find_rpc(routine_id, &rpc_entry, &rpc_cxx);
17391
17392 if (status != RPC_SUCCESS) {
17393 cm_msg(MERROR, "rpc_server_receive_rpc", "Unknown RPC routine_id %d", routine_id);
17394 goto error;
17395 }
17396
17397 if (rpc_cxx)
17398 status = rpc_execute_cxx(sa->recv_sock, routine_id, rpc_entry, buf, sa->convert_flags);
17399 else
17400 status = rpc_execute_old(sa->recv_sock, routine_id, rpc_entry, buf, sa->convert_flags);
17401
17402 if (status == SS_ABORT) {
17403 cm_msg(MERROR, "rpc_server_receive_rpc", "rpc_execute() returned %d, abort", status);
17404 goto error;
17405 }
17406
17407 if (status == SS_EXIT || status == RPC_SHUTDOWN) {
17408 if (rpc_is_mserver())
17409 rpc_debug_printf("Connection to %s:%s closed\n", sa->host_name.c_str(), sa->prog_name.c_str());
17410 goto exit;
17411 }
17412
17413 } while (remaining);
17414
17415 if (buf) {
17416 free(buf);
17417 buf = NULL;
17418 bufsize = 0;
17419 }
17420
17421 return RPC_SUCCESS;
17422
17423 error:
17424
17425 {
17426 char str[80];
17427 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
17428 if (strchr(str, '.'))
17429 *strchr(str, '.') = 0;
17430 cm_msg(MTALK, "rpc_server_receive_rpc", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
17431 }
17432
17433 exit:
17434
17436
17437 if (buf) {
17438 free(buf);
17439 buf = NULL;
17440 bufsize = 0;
17441 }
17442
17443 /* disconnect from experiment as MIDAS server */
17444 if (rpc_is_mserver()) {
17445
17446 if (status != SS_EXIT)
17447 cm_msg(MERROR, "rpc_server_receive_rpc", "mserver unexpected shutdown, status %d", status);
17448
17449 HNDLE hDB, hKey;
17450
17452
17453 /* only disconnect from experiment if previously connected.
17454 Necessary for pure RPC servers (RPC_SRVR) */
17455 if (hDB) {
17459
17461
17463 }
17464 }
17465
17466 bool is_mserver = sa->is_mserver;
17467
17468 sa->close();
17469
17470 /* signal caller a shutdonw */
17471 if (status == RPC_SHUTDOWN)
17472 return status;
17473
17474 /* only the mserver should stop on server connection closure */
17475 if (!is_mserver) {
17476 return SS_SUCCESS;
17477 }
17478
17479 return status;
17480}
static INT rpc_execute_old(INT sock, int xroutine_id, const RPC_LIST &rl, char *buffer, INT convert_flags)
Definition midas.cxx:15198
static INT rpc_execute_cxx(INT sock, int xroutine_id, const RPC_LIST &rl, char *buffer, INT convert_flags)
Definition midas.cxx:15605
static int recv_net_command_realloc(RPC_SERVER_ACCEPTION *sa, char **pbuf, int *pbufsize, INT *remaining)
Definition midas.cxx:14747
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_shutdown()

INT rpc_server_shutdown ( void  )

Definition at line 17685 of file midas.cxx.

17702{
17703 //printf("rpc_server_shutdown!\n");
17704
17705 struct linger ling;
17706
17707 /* close all open connections */
17708 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
17709 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
17711 /* lingering needed for PCTCP */
17712 ling.l_onoff = 1;
17713 ling.l_linger = 0;
17714 setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17716
17717 if (sa->send_sock) {
17718 setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17720 }
17721
17722 if (sa->event_sock) {
17723 setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17725 }
17726 }
17727 }
17728
17729 /* avoid memory leak */
17730 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
17732 if (sa) {
17733 //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
17734 if (sa == _mserver_acception) {
17735 // do not leave behind a stale pointer!
17736 _mserver_acception = NULL;
17737 }
17738 delete sa;
17739 _server_acceptions[idx] = NULL;
17740 }
17741 }
17742
17743 if (_rpc_registered) {
17746 }
17747
17748 /* free suspend structures */
17750
17751 return RPC_SUCCESS;
17752}
INT ss_suspend_exit()
Definition system.cxx:4305
static BOOL _rpc_registered
Definition midas.cxx:258
static int _rpc_listen_socket
Definition midas.cxx:259
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_debug()

INT rpc_set_debug ( void(*)(const char *)  func,
INT  mode 
)

Definition at line 13367 of file midas.cxx.

13387{
13388 _debug_print = func;
13389 _debug_mode = mode;
13390 return RPC_SUCCESS;
13391}
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char *  path)

Definition at line 13297 of file midas.cxx.

13311{
13312 _mserver_path = path;
13313 return RPC_SUCCESS;
13314}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char *  name)

Definition at line 13341 of file midas.cxx.

13359{
13361
13362 return RPC_SUCCESS;
13363}
Here is the caller graph for this function:

◆ rpc_set_opt_tcp_size()

INT rpc_set_opt_tcp_size ( INT  tcp_size)

Definition at line 14414 of file midas.cxx.

14414 {
14415 INT old;
14416
14417 old = _opt_tcp_size;
14418 _opt_tcp_size = tcp_size;
14419 return old;
14420}
Here is the caller graph for this function:

◆ rpc_set_timeout()

INT rpc_set_timeout ( HNDLE  hConn,
int  timeout_msec,
int *  old_timeout_msec 
)

Set RPC timeout

Parameters
hConnRPC connection handle, RPC_HNDLE_MSERVER for mserver connection, RPC_HNDLE_CONNECT for rpc connect timeout
timeout_msecRPC timeout in milliseconds
old_timeout_msecreturns old value of RPC timeout in milliseconds
Returns
RPC_SUCCESS

Definition at line 13231 of file midas.cxx.

13232{
13233 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13234
13235 if (hConn == RPC_HNDLE_MSERVER) {
13236 if (old_timeout_msec)
13237 *old_timeout_msec = _server_connection.rpc_timeout;
13238 _server_connection.rpc_timeout = timeout_msec;
13239 } else if (hConn == RPC_HNDLE_CONNECT) {
13240 if (old_timeout_msec)
13241 *old_timeout_msec = _rpc_connect_timeout;
13242 _rpc_connect_timeout = timeout_msec;
13243 } else {
13245 if (c) {
13246 if (old_timeout_msec)
13247 *old_timeout_msec = c->rpc_timeout;
13248 c->rpc_timeout = timeout_msec;
13249 c->mutex.unlock();
13250 } else {
13251 if (old_timeout_msec)
13252 *old_timeout_msec = 0;
13253 }
13254 }
13255 return RPC_SUCCESS;
13256}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_socket_check_allowed_host()

static INT rpc_socket_check_allowed_host ( int  sock)
static

Definition at line 16785 of file midas.cxx.

16786{
16787 std::string hostname;
16788
16789 int status = ss_socket_get_peer_name(sock, &hostname, NULL);
16790
16791 if (status != SS_SUCCESS)
16792 return status;
16793
16794 status = rpc_check_allowed_host(hostname.c_str());
16795
16796 if (status == RPC_SUCCESS)
16797 return RPC_SUCCESS;
16798
16799 static std::atomic_int max_report(10);
16800 if (max_report > 0) {
16801 max_report--;
16802 if (max_report == 0) {
16803 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
16804 } else {
16805 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\'. Add this host to \"/Experiment/Security/RPC hosts/Allowed hosts\"", hostname.c_str());
16806 }
16807 }
16808
16809 return RPC_NET_ERROR;
16810}
INT rpc_check_allowed_host(const char *hostname)
Definition midas.cxx:16736
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_test_rpc()

int rpc_test_rpc ( )

Definition at line 16644 of file midas.cxx.

16660{
16661 int status;
16663 if (status != RPC_SUCCESS)
16664 return status;
16666 if (status != RPC_SUCCESS)
16667 return status;
16669 if (status != RPC_SUCCESS)
16670 return status;
16672 if (status != RPC_SUCCESS)
16673 return status;
16674 return RPC_SUCCESS;
16675}
int rpc_test_rpc_test2_cxx()
Definition midas.cxx:16215
int rpc_test_rpc_test2()
Definition midas.cxx:16053
int rpc_test_rpc_test3_cxx()
Definition midas.cxx:16375
int rpc_test_rpc_test4_cxx()
Definition midas.cxx:16531
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_test_rpc_test2()

int rpc_test_rpc_test2 ( )

Definition at line 16053 of file midas.cxx.

16069{
16070 int status = RPC_SUCCESS;
16071
16072 printf("rpc_test_rpc_test2!\n");
16073
16074 int int_out = 0;
16075 int int_inout = 456;
16076
16077 char string_out[33];
16078 char string2_out[49];
16079
16080 char string_inout[25];
16081 strcpy(string_inout, "string_inout");
16082
16083 KEY struct_in;
16084
16085 struct_in.type = 111;
16086 struct_in.num_values = 222;
16087 strcpy(struct_in.name, "name");
16088 struct_in.last_written = 333;
16089
16090 KEY struct_out;
16091 KEY struct_inout;
16092
16093 struct_inout.type = 111111;
16094 struct_inout.num_values = 222222;
16095 strcpy(struct_inout.name, "name_name");
16096 struct_inout.last_written = 333333;
16097
16098 uint32_t dwordarray_inout[9];
16099 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
16100
16101 for (int i=0; i<9; i++) {
16102 dwordarray_inout[i] = i*10;
16103 }
16104
16105 char array_in[10];
16106
16107 for (size_t i=0; i<sizeof(array_in); i++) {
16108 array_in[i] = 'a' + i;
16109 }
16110
16111 char array_out[16];
16112 size_t array_out_size = sizeof(array_out);
16113
16114 for (size_t i=0; i<sizeof(array_out); i++) {
16115 array_out[i] = 'Z';
16116 }
16117
16119 123,
16120 &int_out,
16121 &int_inout,
16122 "test string",
16123 string_out, sizeof(string_out),
16124 string2_out, sizeof(string2_out),
16125 string_inout, sizeof(string_inout),
16126 &struct_in,
16127 &struct_out,
16128 &struct_inout,
16129 dwordarray_inout, &dwordarray_inout_size,
16130 array_in, sizeof(array_in),
16131 array_out, &array_out_size
16132 );
16133
16134 if (status != RPC_SUCCESS) {
16135 printf("rpc_call(RPC_TEST2) status %d\n", status);
16136 return status;
16137 }
16138
16139 if (int_out != 789) {
16140 printf("int_out mismatch!\n");
16141 status = 0;
16142 }
16143
16144 if (int_inout != 456*2) {
16145 printf("int_inout mismatch!\n");
16146 status = 0;
16147 }
16148
16149 if (strcmp(string_out, "string_out") != 0) {
16150 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
16151 status = 0;
16152 }
16153
16154 if (strcmp(string2_out, "second string_out") != 0) {
16155 printf("string2_out mismatch [%s] vs [%s]\n", string2_out, "second string_out");
16156 status = 0;
16157 }
16158
16159 if (strcmp(string_inout, "return string_inout") != 0) {
16160 printf("string_inout mismatch [%s] vs [%s]\n", string_inout, "return string_inout");
16161 status = 0;
16162 }
16163
16164 KEY* pkey;
16165
16166 pkey = &struct_in;
16167
16168 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16169
16170 pkey = &struct_out;
16171
16172 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
16173 printf("struct_out mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16174 status = 0;
16175 }
16176
16177 pkey = &struct_inout;
16178
16179 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
16180 printf("struct_inout mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16181 status = 0;
16182 }
16183
16184 if (dwordarray_inout_size != 4*5) {
16185 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
16186 status = 0;
16187 } else {
16188 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
16189 if (dwordarray_inout[i] != i*10+i) {
16190 printf("dwordarray_inout[%d] data mismatch %d vs %zu\n", (int)i, dwordarray_inout[i], i*10+i);
16191 status = 0;
16192 }
16193 }
16194 }
16195
16196 //printf("array_out_size %d\n", array_out_size);
16197 //for (int i=0; i<array_out_size; i++) {
16198 // printf("array_out[%d] is %3d (%c)\n", i, array_out[i], array_out[i]);
16199 //}
16200
16201 if (array_out_size != 15) {
16202 printf("array_out_size mismatch %d vs %d\n", (int)array_out_size, 15);
16203 status = 0;
16204 } else {
16205 if (strcmp(array_out, "test test test") != 0) {
16206 printf("array_out data mismatch\n");
16207 status = 0;
16208 }
16209 }
16210
16211 return status;
16212}
Definition midas.h:1027
INT num_values
Definition midas.h:1029
DWORD type
Definition midas.h:1028
INT last_written
Definition midas.h:1038
char name[NAME_LENGTH]
Definition midas.h:1030
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_test_rpc_test2_cxx()

int rpc_test_rpc_test2_cxx ( )

Definition at line 16215 of file midas.cxx.

16231{
16232 int status = RPC_SUCCESS;
16233
16234 printf("rpc_test_rpc_test2_cxx!\n");
16235
16236 int int_out = 0;
16237 int int_inout = 456;
16238
16239 char string_out[33];
16240 std::string string2_out;
16241 std::string string_inout = "string_inout";
16242
16243 KEY struct_in;
16244
16245 struct_in.type = 111;
16246 struct_in.num_values = 222;
16247 strcpy(struct_in.name, "name");
16248 struct_in.last_written = 333;
16249
16250 KEY struct_out;
16251 KEY struct_inout;
16252
16253 struct_inout.type = 111111;
16254 struct_inout.num_values = 222222;
16255 strcpy(struct_inout.name, "name_name");
16256 struct_inout.last_written = 333333;
16257
16258 uint32_t dwordarray_inout[9];
16259 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
16260
16261 for (int i=0; i<9; i++) {
16262 dwordarray_inout[i] = i*10;
16263 }
16264
16265 std::vector<char> array_in;
16266 int array_in_size = 10;
16267
16268 for (int i=0; i<array_in_size; i++) {
16269 array_in.push_back('a' + i);
16270 }
16271
16272 std::vector<char> array_out;
16273 size_t array_out_size = 16;
16274
16276 123,
16277 &int_out,
16278 &int_inout,
16279 "test string",
16280 string_out, sizeof(string_out),
16281 &string2_out, 48,
16282 &string_inout, 25,
16283 &struct_in,
16284 &struct_out,
16285 &struct_inout,
16286 dwordarray_inout, &dwordarray_inout_size,
16287 &array_in, array_in_size,
16288 &array_out, &array_out_size
16289 );
16290
16291 if (status != RPC_SUCCESS) {
16292 printf("rpc_call(RPC_TEST2_CXX) status %d\n", status);
16293 return status;
16294 }
16295
16296 if (int_out != 789) {
16297 printf("int_out mismatch!\n");
16298 status = 0;
16299 }
16300
16301 if (int_inout != 456*2) {
16302 printf("int_inout mismatch!\n");
16303 status = 0;
16304 }
16305
16306 if (strcmp(string_out, "string_out") != 0) {
16307 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
16308 status = 0;
16309 }
16310
16311 if (string2_out != "second string_out") {
16312 printf("string2_out mismatch [%s] vs [%s]\n", string2_out.c_str(), "second string_out");
16313 status = 0;
16314 }
16315
16316 if (string_inout != "return string_inout") {
16317 printf("string_inout mismatch [%s] vs [%s]\n", string_inout.c_str(), "return string_inout");
16318 status = 0;
16319 }
16320
16321 KEY* pkey;
16322
16323 pkey = &struct_in;
16324
16325 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16326
16327 pkey = &struct_out;
16328
16329 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
16330 printf("struct_out mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16331 status = 0;
16332 }
16333
16334 pkey = &struct_inout;
16335
16336 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
16337 printf("struct_inout mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16338 status = 0;
16339 }
16340
16341 if (dwordarray_inout_size != 4*5) {
16342 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
16343 status = 0;
16344 } else {
16345 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
16346 if (dwordarray_inout[i] != i*10+i) {
16347 printf("dwordarray_inout[%d] data mismatch %d vs %zu\n", (int)i, dwordarray_inout[i], i*10+i);
16348 status = 0;
16349 }
16350 }
16351 }
16352
16353 //printf("array_out_size %d\n", array_out_size);
16354 //for (int i=0; i<array_out_size; i++) {
16355 // printf("array_out[%d] is %3d (%c)\n", i, array_out[i], array_out[i]);
16356 //}
16357
16358 if (array_out_size != 15) {
16359 printf("array_out_size mismatch %d vs %d\n", (int)array_out_size, 15);
16360 status = 0;
16361 } else if (array_out.size() != 15) {
16362 printf("array_out.size() mismatch %d vs %d\n", (int)array_out.size(), 15);
16363 status = 0;
16364 } else {
16365 if (strcmp(array_out.data(), "test test test") != 0) {
16366 printf("array_out data mismatch\n");
16367 status = 0;
16368 }
16369 }
16370
16371 return status;
16372}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_test_rpc_test3_cxx()

int rpc_test_rpc_test3_cxx ( )

Definition at line 16375 of file midas.cxx.

16391{
16392 int status = RPC_SUCCESS;
16393
16394 printf("rpc_test_rpc_test3_cxx!\n");
16395
16396 int int_out = 0;
16397 int int_inout = 456;
16398
16399 char string_out[33];
16400 std::string string2_out;
16401 std::string string_inout = "string_inout";
16402
16403 KEY struct_in;
16404
16405 struct_in.type = 111;
16406 struct_in.num_values = 222;
16407 strcpy(struct_in.name, "name");
16408 struct_in.last_written = 333;
16409
16410 KEY struct_out;
16411 KEY struct_inout;
16412
16413 struct_inout.type = 111111;
16414 struct_inout.num_values = 222222;
16415 strcpy(struct_inout.name, "name_name");
16416 struct_inout.last_written = 333333;
16417
16418 uint32_t dwordarray_inout[9];
16419 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
16420
16421 for (int i=0; i<9; i++) {
16422 dwordarray_inout[i] = i*10;
16423 }
16424
16425 std::vector<char> array_in;
16426 int array_in_size = 10;
16427
16428 for (int i=0; i<array_in_size; i++) {
16429 array_in.push_back('a' + i);
16430 }
16431
16432 std::vector<char> array_out;
16433
16435 123,
16436 &int_out,
16437 &int_inout,
16438 "test string",
16439 string_out, sizeof(string_out),
16440 &string2_out,
16441 &string_inout,
16442 &struct_in,
16443 &struct_out,
16444 &struct_inout,
16445 dwordarray_inout, &dwordarray_inout_size,
16446 &array_in,
16447 &array_out
16448 );
16449
16450 if (status != RPC_SUCCESS) {
16451 printf("rpc_call(RPC_TEST3_CXX) status %d\n", status);
16452 return status;
16453 }
16454
16455 if (int_out != 789) {
16456 printf("int_out mismatch!\n");
16457 status = 0;
16458 }
16459
16460 if (int_inout != 456*2) {
16461 printf("int_inout mismatch!\n");
16462 status = 0;
16463 }
16464
16465 if (strcmp(string_out, "string_out") != 0) {
16466 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
16467 status = 0;
16468 }
16469
16470 if (string2_out != "second string_out") {
16471 printf("string2_out mismatch [%s] vs [%s]\n", string2_out.c_str(), "second string_out");
16472 status = 0;
16473 }
16474
16475 if (string_inout != "return string_inout") {
16476 printf("string_inout mismatch [%s] vs [%s]\n", string_inout.c_str(), "return string_inout");
16477 status = 0;
16478 }
16479
16480 KEY* pkey;
16481
16482 pkey = &struct_in;
16483
16484 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16485
16486 pkey = &struct_out;
16487
16488 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
16489 printf("struct_out mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16490 status = 0;
16491 }
16492
16493 pkey = &struct_inout;
16494
16495 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
16496 printf("struct_inout mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16497 status = 0;
16498 }
16499
16500 if (dwordarray_inout_size != 4*5) {
16501 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
16502 status = 0;
16503 } else {
16504 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
16505 if (dwordarray_inout[i] != i*10+i) {
16506 printf("dwordarray_inout[%d] data mismatch %d vs %zu\n", (int)i, dwordarray_inout[i], i*10+i);
16507 status = 0;
16508 }
16509 }
16510 }
16511
16512 //printf("array_out_size %d\n", array_out_size);
16513 //for (int i=0; i<array_out_size; i++) {
16514 // printf("array_out[%d] is %3d (%c)\n", i, array_out[i], array_out[i]);
16515 //}
16516
16517 if (array_out.size() != 15) {
16518 printf("array_out.size() mismatch %d vs %d\n", (int)array_out.size(), 15);
16519 status = 0;
16520 } else {
16521 if (strcmp(array_out.data(), "test test test") != 0) {
16522 printf("array_out data mismatch\n");
16523 status = 0;
16524 }
16525 }
16526
16527 return status;
16528}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_test_rpc_test4_cxx()

int rpc_test_rpc_test4_cxx ( )

Definition at line 16531 of file midas.cxx.

16547{
16548 int status = RPC_SUCCESS;
16549
16550 printf("rpc_test_rpc_test4_cxx!\n");
16551
16552 int int_out = 0;
16553 int int_inout = 456;
16554
16555 std::string string_in = "test string";
16556 std::string string_out;
16557 std::string string_inout = "string_inout";
16558
16559 std::vector<char> array_in;
16560 int array_in_size = 10;
16561
16562 for (int i=0; i<array_in_size; i++) {
16563 array_in.push_back('a' + i);
16564 }
16565
16566 std::vector<char> array_out;
16567
16568 std::vector<char> array_inout;
16569 int array_inout_size = 6;
16570
16571 for (int i=0; i<array_inout_size; i++) {
16572 array_inout.push_back('0' + i);
16573 }
16574
16576 123,
16577 &int_out,
16578 &int_inout,
16579 &string_in,
16580 &string_out,
16581 &string_inout,
16582 &array_in,
16583 &array_out,
16584 &array_inout
16585 );
16586
16587 if (status != RPC_SUCCESS) {
16588 printf("rpc_call(RPC_TEST4_CXX) status %d\n", status);
16589 return status;
16590 }
16591
16592 if (int_out != 789) {
16593 printf("int_out mismatch!\n");
16594 status = 0;
16595 }
16596
16597 if (int_inout != 456*2) {
16598 printf("int_inout mismatch!\n");
16599 status = 0;
16600 }
16601
16602 if (string_out != "return string_out") {
16603 printf("string_out mismatch [%s] vs [%s]\n", string_out.c_str(), "return string_out");
16604 status = 0;
16605 }
16606
16607 if (string_inout != "return string_inout") {
16608 printf("string_inout mismatch [%s] vs [%s]\n", string_inout.c_str(), "return string_inout");
16609 status = 0;
16610 }
16611
16612 if (array_out.size() != 15) {
16613 printf("array_out.size() mismatch %d vs %d\n", (int)array_out.size(), 15);
16614 status = 0;
16615 } else {
16616 if (strcmp(array_out.data(), "test test test") != 0) {
16617 printf("array_out data mismatch\n");
16618 status = 0;
16619 }
16620 }
16621
16622 if (array_inout.size() != 12) {
16623 printf("array_inout.size() mismatch %d vs %d\n", (int)array_inout.size(), 12);
16624 status = 0;
16625 } else {
16626 for (int i=0; i<6; i++) {
16627 if (array_inout[i] != '0' + i) {
16628 printf("array_inout data mismatch, index %d, value %d should be %d\n", i, array_inout[i], ('0'+i));
16629 status = 0;
16630 }
16631 }
16632 for (int i=6; i<12; i++) {
16633 if (array_inout[i] != 2*('0' + (i-6))) {
16634 printf("array_inout data mismatch, index %d, value %d should be %d\n", i, array_inout[i], 2*('0'+i));
16635 status = 0;
16636 }
16637 }
16638 }
16639
16640 return status;
16641}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_tid_name()

const char * rpc_tid_name ( INT  id)

Definition at line 11997 of file midas.cxx.

11997 {
11998 if (id >= 0 && id < TID_LAST)
11999 return tid_name[id];
12000 else
12001 return "<unknown>";
12002}
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 12004 of file midas.cxx.

12004 {
12005 if (id >= 0 && id < TID_LAST)
12006 return tid_name_old[id];
12007 else
12008 return "<unknown>";
12009}
Here is the caller graph for this function:

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11990 of file midas.cxx.

11990 {
11991 if (id >= 0 && id < TID_LAST)
11992 return tid_size[id];
11993
11994 return 0;
11995}
static const int tid_size[]
Definition midas.cxx:66
Here is the caller graph for this function:

◆ rpc_transition_dispatch()

static INT rpc_transition_dispatch ( INT  idx,
void *  prpc_param[] 
)
static

Definition at line 14606 of file midas.cxx.

14625{
14626 /* erase error string */
14627 *(CSTRING(2)) = 0;
14628
14629 if (idx == RPC_RC_TRANSITION) {
14630 // find registered handler
14631 // NB: this code should match same code in cm_transition_call_direct()
14632 // NB: only use the first handler, this is how MIDAS always worked
14633 // NB: we could run all handlers, but we can return the status and error string of only one of them.
14634 _trans_table_mutex.lock();
14635 size_t n = _trans_table.size();
14636 _trans_table_mutex.unlock();
14637
14638 for (size_t i = 0; i < n; i++) {
14639 _trans_table_mutex.lock();
14641 _trans_table_mutex.unlock();
14642
14643 if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14644 if (tt.func) {
14645 /* execute callback if defined */
14646 return tt.func(CINT(1), CSTRING(2));
14647 } else {
14648 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14649 /* store transition in FIFO */
14652 _tr_fifo[_tr_fifo_wp].trans_time = time(NULL);
14654 _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14655 // implicit unlock
14656 return RPC_SUCCESS;
14657 }
14658 }
14659 }
14660 // no handler for this transition
14661 cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14662 return CM_SUCCESS;
14663 } else {
14664 cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14665 return RPC_INVALID_ID;
14666 }
14667}
#define CM_SUCCESS
Definition midas.h:582
#define RPC_RC_TRANSITION
Definition mrpc.h:117
static std::vector< TRANS_TABLE > _trans_table
Definition midas.cxx:248
static std::mutex _trans_table_mutex
Definition midas.cxx:247
#define CINT(_i)
Definition midas.h:1558
#define CSTRING(_i)
Definition midas.h:1582
time_t trans_time
Definition midas.cxx:14597
int sequence_number
Definition midas.cxx:14598
INT sequence_number
Definition midas.cxx:243
INT(* func)(INT, char *)
Definition midas.cxx:244
INT transition
Definition midas.cxx:242
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_va_arg()

void rpc_va_arg ( va_list *  arg_ptr,
INT  arg_type,
void *  arg 
)

Definition at line 13426 of file midas.cxx.

13426 {
13427 switch (arg_type) {
13428 /* On the stack, the minimum parameter size is sizeof(int).
13429 To avoid problems on little endian systems, treat all
13430 smaller parameters as int's */
13431 case TID_UINT8:
13432 case TID_INT8:
13433 case TID_CHAR:
13434 case TID_UINT16:
13435 case TID_INT16:
13436 *((int *) arg) = va_arg(*arg_ptr, int);
13437 break;
13438
13439 case TID_INT32:
13440 case TID_BOOL:
13441 *((INT *) arg) = va_arg(*arg_ptr, INT);
13442 break;
13443
13444 case TID_UINT32:
13445 *((DWORD *) arg) = va_arg(*arg_ptr, DWORD);
13446 break;
13447
13448 /* float variables are passed as double by the compiler */
13449 case TID_FLOAT:
13450 *((float *) arg) = (float) va_arg(*arg_ptr, double);
13451 break;
13452
13453 case TID_DOUBLE:
13454 *((double *) arg) = va_arg(*arg_ptr, double);
13455 break;
13456
13457 case TID_ARRAY:
13458 *((char **) arg) = va_arg(*arg_ptr, char *);
13459 break;
13460 }
13461}
Here is the caller graph for this function:

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double *  var)

Definition at line 11875 of file midas.cxx.

11875 {
11876 unsigned short int i1, i2, i3, i4;
11877
11878 /* swap words */
11879 i1 = *((short int *) (var) + 3);
11880 i2 = *((short int *) (var) + 2);
11881 i3 = *((short int *) (var) + 1);
11882 i4 = *((short int *) (var));
11883
11884 /* correct exponent */
11885 if (i4 != 0)
11886 i4 -= 0x20;
11887
11888 *((short int *) (var) + 3) = i4;
11889 *((short int *) (var) + 2) = i3;
11890 *((short int *) (var) + 1) = i2;
11891 *((short int *) (var)) = i1;
11892}
Here is the caller graph for this function:

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float *  var)

Definition at line 11859 of file midas.cxx.

11859 {
11860 unsigned short int lo, hi;
11861
11862 /* swap hi and lo word */
11863 lo = *((short int *) (var) + 1);
11864 hi = *((short int *) (var));
11865
11866 /* correct exponent */
11867 if (hi != 0)
11868 hi -= 0x100;
11869
11870 *((short int *) (var) + 1) = hi;
11871 *((short int *) (var)) = lo;
11872
11873}
Here is the caller graph for this function:

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11737 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11736 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11744 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13281 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11809 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11740 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11743 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11739 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14602 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14601 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14604 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14603 of file midas.cxx.

◆ gAllowedHosts

std::vector<std::string> gAllowedHosts
static

Definition at line 16678 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 16679 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11806 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11807 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 15194 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 15195 of file midas.cxx.