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 11683 of file midas.cxx.

11684{
11685 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11686
11687 if (is_mserver) {
11688 assert(_mserver_acception == this);
11689 _mserver_acception = NULL;
11690 is_mserver = false;
11691 }
11692
11693 /* close server connection */
11694 if (recv_sock)
11696 if (send_sock)
11698 if (event_sock)
11700
11701 /* free TCP cache */
11702 if (net_buffer) {
11703 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11704 free(net_buffer);
11705 net_buffer = NULL;
11706 net_buffer_size = 0;
11707 }
11708
11709 /* mark this entry as invalid */
11710 clear();
11711}
INT ss_socket_close(int *sockp)
Definition system.cxx:5310
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11651
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 14577 of file midas.cxx.

14601{
14602 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14603
14604 if (_tr_fifo_wp == _tr_fifo_rp)
14605 return FALSE;
14606
14607 if (transition)
14609
14610 if (run_number)
14612
14613 if (trans_time)
14614 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14615
14616 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14617
14618 // implicit unlock
14619 return TRUE;
14620}
#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:14511
static int _tr_fifo_wp
Definition midas.cxx:14510
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14509
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14508
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14502
int run_number
Definition midas.cxx:14503
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 12071 of file midas.cxx.

12071 {
12072 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
12073 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
12074 /* update a changed record */
12075 HNDLE hDB = *((INT *) nc->param);
12076 HNDLE hKeyRoot = *((INT *) nc->param + 1);
12077 HNDLE hKey = *((INT *) nc->param + 2);
12078 int index = *((INT *) nc->param + 3);
12079 return db_update_record_local(hDB, hKeyRoot, hKey, index);
12080 }
12081 return CM_VERSION_MISMATCH;
12082}
#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 14842 of file midas.cxx.

14864{
14865 int sock = psa->event_sock;
14866
14867 //printf("recv_event_server: idx %d, buffer %p, buffer_size %d\n", idx, buffer, buffer_size);
14868
14869 const size_t header_size = (sizeof(EVENT_HEADER) + sizeof(INT));
14870
14871 char header_buf[header_size];
14872
14873 // First read the header.
14874 //
14875 // Data format is:
14876 // INT buffer handle (4 bytes)
14877 // EVENT_HEADER (16 bytes)
14878 // event data
14879 // ALIGN8() padding
14880 // ...next event
14881
14882 int hrd = recv_tcp2(sock, header_buf, header_size, 1);
14883
14884 if (hrd == 0) {
14885 // timeout waiting for data
14886 return 0;
14887 }
14888
14889 /* abort if connection broken */
14890 if (hrd < 0) {
14891 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d", hrd);
14892 return -1;
14893 }
14894
14895 if (hrd < (int) header_size) {
14896 int hrd1 = recv_tcp2(sock, header_buf + hrd, header_size - hrd, 0);
14897
14898 /* abort if connection broken */
14899 if (hrd1 <= 0) {
14900 cm_msg(MERROR, "recv_event_server", "recv_tcp2(more header) returned %d", hrd1);
14901 return -1;
14902 }
14903
14904 hrd += hrd1;
14905 }
14906
14907 /* abort if connection broken */
14908 if (hrd != (int) header_size) {
14909 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d instead of %d", hrd, (int) header_size);
14910 return -1;
14911 }
14912
14913 INT *pbh = (INT *) header_buf;
14914 EVENT_HEADER *pevent = (EVENT_HEADER *) (((INT *) header_buf) + 1);
14915
14916 /* convert header little endian/big endian */
14917 if (psa->convert_flags) {
14924 }
14925
14926 int event_size = pevent->data_size + sizeof(EVENT_HEADER);
14927 int total_size = ALIGN8(event_size);
14928
14929 //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);
14930
14931 if (pevent->data_size == 0) {
14932 for (int i=0; i<5; i++) {
14933 printf("recv_event_server: header[%d]: 0x%08x\n", i, pbh[i]);
14934 }
14935 abort();
14936 }
14937
14938 /* check for sane event size */
14939 if (event_size <= 0 || total_size <= 0) {
14940 cm_msg(MERROR, "recv_event_server",
14941 "received event header with invalid data_size %d: event_size %d, total_size %d", pevent->data_size,
14942 event_size, total_size);
14943 return -1;
14944 }
14945
14946 //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);
14947
14948
14949 int bufsize = sizeof(INT) + total_size;
14950
14951 // Second, check that output buffer is big enough
14952
14953 /* check if data part fits in buffer */
14954 if (*pbuffer_size < bufsize) {
14955 int newsize = 1024 + ALIGN8(bufsize);
14956
14957 //printf("recv_event_server: buffer realloc %d -> %d\n", *pbuffer_size, newsize);
14958
14959 char *newbuf = (char *) realloc(*pbuffer, newsize);
14960 if (newbuf == NULL) {
14961 cm_msg(MERROR, "recv_event_server", "cannot realloc() event buffer from %d to %d bytes", *pbuffer_size,
14962 newsize);
14963 return -1;
14964 }
14965 *pbuffer = newbuf;
14966 *pbuffer_size = newsize;
14967 }
14968
14969 // Third, copy header into output buffer
14970
14971 memcpy(*pbuffer, header_buf, header_size);
14972
14973 // Forth, read the event data
14974
14975 int to_read = sizeof(INT) + total_size - header_size;
14976 int rptr = header_size;
14977
14978 if (to_read > 0) {
14979 int drd = recv_tcp2(sock, (*pbuffer) + rptr, to_read, 0);
14980
14981 /* abort if connection broken */
14982 if (drd <= 0) {
14983 cm_msg(MERROR, "recv_event_server", "recv_tcp2(data) returned %d instead of %d", drd, to_read);
14984 return -1;
14985 }
14986 }
14987
14988 return bufsize;
14989}
#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:931
void rpc_convert_single(void *data, INT tid, INT flags, INT convert_flags)
Definition midas.cxx:11821
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 14654 of file midas.cxx.

14682{
14683 char *buffer = NULL; // buffer is changed to point to *pbuf when we receive the NET_COMMAND header
14684
14685 int sock = sa->recv_sock;
14686
14687 if (!sa->net_buffer) {
14688 if (sa->is_mserver)
14690 else
14692
14693 sa->net_buffer = (char *) malloc(sa->net_buffer_size);
14694 //printf("sa %p idx %d, net_buffer %p+%d\n", sa, idx, sa->net_buffer, sa->net_buffer_size);
14695 sa->write_ptr = 0;
14696 sa->read_ptr = 0;
14697 sa->misalign = 0;
14698 }
14699 if (!sa->net_buffer) {
14700 cm_msg(MERROR, "recv_net_command_realloc", "Cannot allocate %d bytes for network buffer", sa->net_buffer_size);
14701 return -1;
14702 }
14703
14704 int copied = 0;
14705 int param_size = -1;
14706
14707 int write_ptr = sa->write_ptr;
14708 int read_ptr = sa->read_ptr;
14709 int misalign = sa->misalign;
14710 char *net_buffer = sa->net_buffer;
14711
14712 do {
14713 if (write_ptr - read_ptr >= (INT) sizeof(NET_COMMAND_HEADER) - copied) {
14714 if (param_size == -1) {
14715 if (copied > 0) {
14716 /* assemble split header */
14717 memcpy(buffer + copied, net_buffer + read_ptr, (INT) sizeof(NET_COMMAND_HEADER) - copied);
14718 NET_COMMAND *nc = (NET_COMMAND *) (buffer);
14719 param_size = (INT) nc->header.param_size;
14720 } else {
14721 NET_COMMAND *nc = (NET_COMMAND *) (net_buffer + read_ptr);
14722 param_size = (INT) nc->header.param_size;
14723 }
14724
14725 if (sa->convert_flags)
14726 rpc_convert_single(&param_size, TID_UINT32, 0, sa->convert_flags);
14727 }
14728
14729 //printf("recv_net_command_realloc: param_size %d, NET_COMMAND_HEADER %d, buffer_size %d\n", param_size, (int)sizeof(NET_COMMAND_HEADER), *pbufsize);
14730
14731 /* check if parameters fit in buffer */
14732 if (*pbufsize < (param_size + (int) sizeof(NET_COMMAND_HEADER))) {
14733 int new_size = param_size + sizeof(NET_COMMAND_HEADER) + 1024;
14734 char *p = (char *) realloc(*pbuf, new_size);
14735 //printf("recv_net_command_realloc: reallocate buffer %d -> %d, %p\n", *pbufsize, new_size, p);
14736 if (p == NULL) {
14737 cm_msg(MERROR, "recv_net_command_realloc", "cannot reallocate buffer from %d bytes to %d bytes", *pbufsize, new_size);
14738 sa->read_ptr = 0;
14739 sa->write_ptr = 0;
14740 return -1;
14741 }
14742 *pbuf = p;
14743 *pbufsize = new_size;
14744 }
14745
14746 buffer = *pbuf;
14747
14748 /* check if we have all parameters in buffer */
14749 if (write_ptr - read_ptr >= param_size + (INT) sizeof(NET_COMMAND_HEADER) - copied)
14750 break;
14751 }
14752
14753 /* not enough data, so copy partially and get new */
14754 int size = write_ptr - read_ptr;
14755
14756 if (size > 0) {
14757 memcpy(buffer + copied, net_buffer + read_ptr, size);
14758 copied += size;
14759 read_ptr = write_ptr;
14760 }
14761#ifdef OS_UNIX
14762 do {
14763 write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14764
14765 /* don't return if an alarm signal was cought */
14766 } while (write_ptr == -1 && errno == EINTR);
14767#else
14768 write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14769#endif
14770
14771 /* abort if connection broken */
14772 if (write_ptr <= 0) {
14773 if (write_ptr == 0)
14774 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());
14775 else
14776 cm_msg(MERROR, "recv_net_command_realloc", "recv() returned %d, errno: %d (%s)", write_ptr, errno, strerror(errno));
14777
14778 if (remaining)
14779 *remaining = 0;
14780
14781 return write_ptr;
14782 }
14783
14784 read_ptr = misalign;
14785 write_ptr += misalign;
14786
14787 misalign = write_ptr % 8;
14788 } while (TRUE);
14789
14790 /* copy rest of parameters */
14791 int size = param_size + sizeof(NET_COMMAND_HEADER) - copied;
14792 memcpy(buffer + copied, net_buffer + read_ptr, size);
14793 read_ptr += size;
14794
14795 if (remaining) {
14796 /* don't keep rpc_server_receive in an infinite loop */
14797 if (write_ptr - read_ptr < param_size)
14798 *remaining = 0;
14799 else
14800 *remaining = write_ptr - read_ptr;
14801 }
14802
14803 sa->write_ptr = write_ptr;
14804 sa->read_ptr = read_ptr;
14805 sa->misalign = misalign;
14806
14807 return size + copied;
14808}
#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 14812 of file midas.cxx.

14830{
14831 /* figure out to which connection socket belongs */
14832 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14833 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14834 return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14835 }
14836
14837 return 0;
14838}
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition midas.cxx:11650
Here is the caller graph for this function:

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char *  hostname)

Definition at line 16603 of file midas.cxx.

16620{
16621 //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
16622
16623 gAllowedHostsMutex.lock();
16624 gAllowedHosts.push_back(hostname);
16625 gAllowedHostsEnabled = true;
16626 gAllowedHostsMutex.unlock();
16627
16628 return RPC_SUCCESS;
16629}
#define RPC_SUCCESS
Definition midas.h:699
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition midas.cxx:16575
static std::vector< std::string > gAllowedHosts
Definition midas.cxx:16574
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 11723 of file midas.cxx.

11723 {
11724 *convert_flags = 0;
11725
11726 /* big/little endian conversion */
11727 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11728 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11729 && (hw_type & DRI_BIG_ENDIAN)))
11730 *convert_flags |= CF_ENDIAN;
11731
11732 /* float conversion between IEEE and VAX G */
11733 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11734 *convert_flags |= CF_VAX2IEEE;
11735
11736 /* float conversion between VAX G and IEEE */
11737 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11738 *convert_flags |= CF_IEEE2VAX;
11739
11741 //if (remote_hw_type & DR_ASCII)
11742 // *convert_flags |= CF_ASCII;
11743}
#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:1595
#define CF_IEEE2VAX
Definition midas.h:1596
#define CF_VAX2IEEE
Definition midas.h:1597
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 14124 of file midas.cxx.

14148{
14149 va_list ap;
14150 INT i, status;
14151
14152 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
14153 routine_id &= ~RPC_NO_REPLY;
14154
14155 //if (rpc_no_reply)
14156 // printf("rpc_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
14157
14158 int send_sock = _server_connection.send_sock;
14159 int rpc_timeout = _server_connection.rpc_timeout;
14160
14161 if (!send_sock) {
14162 fprintf(stderr, "rpc_call(routine_id=%d) failed, no connection to mserver.\n", routine_id);
14163 return RPC_NET_ERROR;
14164 }
14165
14166 if (!_mutex_rpc) {
14167 /* create a local mutex for multi-threaded applications */
14169 }
14170
14171 status = ss_mutex_wait_for(_mutex_rpc, 10000 + rpc_timeout);
14172 if (status != SS_SUCCESS) {
14173 cm_msg(MERROR, "rpc_call", "Mutex timeout");
14174 return RPC_MUTEX_TIMEOUT;
14175 }
14176
14177 /* find rpc definition */
14178
14179 RPC_LIST rpc_entry;
14180 bool rpc_cxx = false;
14181
14182 status = rpc_find_rpc(routine_id, &rpc_entry, &rpc_cxx);
14183
14184 if (status != RPC_SUCCESS) {
14186 cm_msg(MERROR, "rpc_call", "invalid rpc ID (%d)", routine_id);
14187 return RPC_INVALID_ID;
14188 }
14189
14190 const char* rpc_name = rpc_entry.name;
14191
14192 /* prepare output buffer */
14193
14194 NET_COMMAND* nc = NULL;
14195
14196 /* examine variable argument list and convert it to parameter array */
14197 va_start(ap, routine_id);
14198
14199 if (rpc_cxx)
14200 rpc_call_encode_cxx(ap, rpc_entry, &nc);
14201 else
14202 rpc_call_encode(ap, rpc_entry, &nc);
14203
14204 va_end(ap);
14205
14206 nc->header.routine_id = routine_id;
14207
14208 if (rpc_no_reply)
14210
14211 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
14212
14213 /* do not wait for reply if requested RPC_NO_REPLY */
14214 if (rpc_no_reply) {
14215 i = send_tcp(send_sock, (char *) nc, send_size, 0);
14216
14217 if (i != send_size) {
14219 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
14220 free(nc);
14221 return RPC_NET_ERROR;
14222 }
14223
14225 free(nc);
14226 return RPC_SUCCESS;
14227 }
14228
14229 /* in TCP mode, send and wait for reply on send socket */
14230 i = send_tcp(send_sock, (char *) nc, send_size, 0);
14231 if (i != send_size) {
14233 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
14234 free(nc);
14235 return RPC_NET_ERROR;
14236 }
14237
14238 free(nc);
14239 nc = NULL;
14240
14241 bool restore_watchdog_timeout = false;
14242 BOOL watchdog_call;
14243 DWORD watchdog_timeout;
14244 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
14245
14246 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, rpc_timeout);
14247
14248 if (!rpc_is_remote()) {
14249 // if RPC is remote, we are connected to an mserver,
14250 // the mserver takes care of watchdog timeouts.
14251 // otherwise we should make sure the watchdog timeout
14252 // is longer than the RPC timeout. K.O.
14253 if (rpc_timeout >= (int) watchdog_timeout) {
14254 restore_watchdog_timeout = true;
14255 cm_set_watchdog_params_local(watchdog_call, rpc_timeout + 1000);
14256 }
14257 }
14258
14259 DWORD rpc_status = 0;
14260 DWORD buf_size = 0;
14261 char* buf = NULL;
14262
14263 status = ss_recv_net_command(send_sock, &rpc_status, &buf_size, &buf, rpc_timeout);
14264
14265 if (restore_watchdog_timeout) {
14266 cm_set_watchdog_params_local(watchdog_call, watchdog_timeout);
14267 }
14268
14269 /* drop the mutex, we are done with the socket, argument unpacking is done from our own buffer */
14270
14272
14273 /* check for reply errors */
14274
14275 if (status == SS_TIMEOUT) {
14276 cm_msg(MERROR, "rpc_call", "routine \"%s\": timeout waiting for reply, program abort", rpc_name);
14277 if (buf)
14278 free(buf);
14279 abort(); // cannot continue - our mserver is not talking to us!
14280 return RPC_TIMEOUT;
14281 }
14282
14283 if (status != SS_SUCCESS) {
14284 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, ss_recv_net_command() status %d, program abort", rpc_name, status);
14285 if (buf)
14286 free(buf);
14287 abort(); // cannot continue - something is wrong with our mserver connection
14288 return RPC_NET_ERROR;
14289 }
14290
14291 if (rpc_status == RPC_INVALID_ID) {
14292 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, unknown RPC, status %d", rpc_name, rpc_status);
14293 if (buf)
14294 free(buf);
14295 return rpc_status;
14296 }
14297
14298 /* extract result variables and place it to argument list */
14299
14300 va_start(ap, routine_id);
14301
14302 if (rpc_cxx)
14303 status = rpc_call_decode_cxx(ap, rpc_entry, buf, buf_size);
14304 else
14305 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
14306
14307 if (status != RPC_SUCCESS) {
14308 rpc_status = status;
14309 }
14310
14311 va_end(ap);
14312
14313 if (buf)
14314 free(buf);
14315
14316 return rpc_status;
14317}
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3341
INT cm_set_watchdog_params_local(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3260
#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:12901
static void rpc_call_encode(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13371
static void rpc_call_encode_cxx(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13616
static int rpc_find_rpc(int routine_id, RPC_LIST *pentry, bool *prpc_cxx)
Definition midas.cxx:13909
static int rpc_call_decode(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13544
static RPC_SERVER_CONNECTION _server_connection
Definition midas.cxx:11646
static int rpc_call_decode_cxx(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13816
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:1583
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 13544 of file midas.cxx.

13545{
13546 //printf("rpc_call_decode!\n");
13547
13548 bool debug = false;
13549
13550 if (debug)
13551 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13552
13553 /* extract result variables and place it to argument list */
13554
13555 const char* param_ptr = buf;
13556
13557 for (int i = 0; rl.param[i].tid != 0; i++) {
13558 int tid = rl.param[i].tid;
13559 int flags = rl.param[i].flags;
13560 int arg_type = 0;
13561
13562 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13563 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13564 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13565
13566 if (bpointer)
13567 arg_type = TID_ARRAY;
13568 else
13569 arg_type = rl.param[i].tid;
13570
13571 if (tid == TID_FLOAT && !bpointer)
13572 arg_type = TID_DOUBLE;
13573
13574 char arg[8];
13575 rpc_va_arg(&ap, arg_type, arg);
13576
13577 if (rl.param[i].flags & RPC_OUT) {
13578
13579 if (param_ptr == NULL) {
13580 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);
13581 return RPC_NET_ERROR;
13582 }
13583
13584 tid = rl.param[i].tid;
13585 int arg_size = rpc_tid_size(tid);
13586
13587 if (tid == TID_STRING || tid == TID_LINK)
13588 arg_size = strlen((char *) (param_ptr)) + 1;
13589
13590 if (flags & RPC_VARARRAY) {
13591 arg_size = *((INT *) param_ptr);
13592 param_ptr += ALIGN8(sizeof(INT));
13593 }
13594
13595 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13596 arg_size = rl.param[i].n;
13597
13598 /* parameter size is always aligned */
13599 int param_size = ALIGN8(arg_size);
13600
13601 /* return parameters are always pointers */
13602 if (*((char **) arg)) {
13603 if (debug)
13604 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);
13605 memcpy((void *) *((char **) arg), param_ptr, arg_size);
13606 }
13607
13608 param_ptr += param_size;
13609 }
13610 }
13611
13612 return RPC_SUCCESS;
13613}
#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:13333
INT rpc_tid_size(INT id)
Definition midas.cxx:11897
BOOL debug
debug printouts
Definition mana.cxx:254
#define RPC_OUT
Definition midas.h:1564
#define RPC_POINTER
Definition midas.h:1565
#define RPC_VARARRAY
Definition midas.h:1567
#define RPC_FIXARRAY
Definition midas.h:1566
RPC_PARAM param[MAX_RPC_PARAMS]
Definition midas.h:1584
INT id
Definition midas.h:1582
WORD flags
Definition midas.h:1575
WORD tid
Definition midas.h:1574
INT n
Definition midas.h:1576
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 13816 of file midas.cxx.

13817{
13818 //printf("rpc_call_decode_cxx!\n");
13819
13820 bool debug = false;
13821
13822 //if (rl.id == RPC_TEST2)
13823 // debug = true;
13824
13825 //if (rl.id == RPC_TEST2_CXX)
13826 // debug = true;
13827
13828 if (debug)
13829 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13830
13831 /* extract result variables and place it to argument list */
13832
13833 const char* param_ptr = buf;
13834
13835 for (int i = 0; rl.param[i].tid != 0; i++) {
13836 const int tid = rl.param[i].tid;
13837 const int flags = rl.param[i].flags;
13838 int arg_type = 0;
13839
13840 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13841 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13842 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13843
13844 if (bpointer)
13845 arg_type = TID_ARRAY;
13846 else
13847 arg_type = tid;
13848
13849 if (tid == TID_FLOAT && !bpointer)
13850 arg_type = TID_DOUBLE;
13851
13852 char arg[sizeof(double)+sizeof(uint64_t)+sizeof(char*)];
13853 rpc_va_arg(&ap, arg_type, arg);
13854
13855 if (flags & RPC_OUT) {
13856
13857 if (param_ptr == NULL) {
13858 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);
13859 return RPC_NET_ERROR;
13860 }
13861
13862 int arg_size = rpc_tid_size(tid);
13863
13864 if (tid == TID_STRING || tid == TID_LINK) {
13865 arg_size = strlen((char *) (param_ptr)) + 1;
13866
13867 if (debug)
13868 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));
13869 }
13870
13871 if (flags & RPC_VARARRAY) {
13872 arg_size = *((INT *) param_ptr);
13873 param_ptr += ALIGN8(sizeof(INT));
13874 }
13875
13876 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13877 arg_size = rl.param[i].n;
13878
13879 /* parameter size is always aligned */
13880 int param_size = ALIGN8(arg_size);
13881
13882 /* return parameters are always pointers */
13883 void* parg = *(char**) arg;
13884 if (parg) {
13885 if ((tid == TID_STRING) && (flags & RPC_CXX)) {
13886 if (debug)
13887 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);
13888 *(std::string*)parg = param_ptr;
13889 } else if ((tid == TID_ARRAY) && (flags & RPC_CXX)) {
13890 if (debug)
13891 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);
13892 std::vector<char>* pvec = (std::vector<char>*)parg;
13893 pvec->clear();
13894 pvec->insert(pvec->end(), param_ptr, param_ptr + arg_size);
13895 } else {
13896 if (debug)
13897 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);
13898 memcpy(parg, param_ptr, arg_size);
13899 }
13900 }
13901
13902 param_ptr += param_size;
13903 }
13904 }
13905
13906 return RPC_SUCCESS;
13907}
#define RPC_CXX
Definition midas.h:1569
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 13371 of file midas.cxx.

13372{
13373 //printf("rpc_call_encode!\n");
13374
13375 bool debug = false;
13376
13377 if (debug) {
13378 printf("encode rpc_id %d \"%s\"\n", rl.id, rl.name);
13379 for (int i=0; rl.param[i].tid != 0; i++) {
13380 int tid = rl.param[i].tid;
13381 int flags = rl.param[i].flags;
13382 int n = rl.param[i].n;
13383 printf("i=%d, tid %d, flags 0x%x, n %d\n", i, tid, flags, n);
13384 }
13385 }
13386
13387 char args[MAX_RPC_PARAMS][8];
13388
13389 for (int i=0; rl.param[i].tid != 0; i++) {
13390 int tid = rl.param[i].tid;
13391 int flags = rl.param[i].flags;
13392 int arg_type = 0;
13393
13394 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13395 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13396 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13397
13398 if (bpointer)
13399 arg_type = TID_ARRAY;
13400 else
13401 arg_type = tid;
13402
13403 /* floats are passed as doubles, at least under NT */
13404 if (tid == TID_FLOAT && !bpointer)
13405 arg_type = TID_DOUBLE;
13406
13407 //printf("arg %d, tid %d, flags 0x%x, arg_type %d, bpointer %d\n", i, tid, flags, arg_type, bpointer);
13408
13409 rpc_va_arg(&ap, arg_type, args[i]);
13410 }
13411
13412 size_t buf_size = sizeof(NET_COMMAND) + 4 * 1024;
13413 char* buf = (char *)malloc(buf_size);
13414 assert(buf);
13415
13416 (*nc) = (NET_COMMAND*) buf;
13417
13418 /* find out if we are on a big endian system */
13419 bool bbig = ((rpc_get_hw_type() & DRI_BIG_ENDIAN) > 0);
13420
13421 char* param_ptr = (*nc)->param;
13422
13423 for (int i=0; rl.param[i].tid != 0; i++) {
13424 int tid = rl.param[i].tid;
13425 int flags = rl.param[i].flags;
13426 int arg_type = 0;
13427
13428 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13429 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13430 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13431
13432 if (bpointer)
13433 arg_type = TID_ARRAY;
13434 else
13435 arg_type = tid;
13436
13437 /* floats are passed as doubles, at least under NT */
13438 if (tid == TID_FLOAT && !bpointer)
13439 arg_type = TID_DOUBLE;
13440
13441 /* get pointer to argument */
13442 //char arg[8];
13443 //rpc_va_arg(&ap, arg_type, arg);
13444
13445 char* arg = args[i];
13446
13447 /* shift 1- and 2-byte parameters to the LSB on big endian systems */
13448 if (bbig) {
13449 if (tid == TID_UINT8 || tid == TID_CHAR || tid == TID_INT8) {
13450 arg[0] = arg[3];
13451 }
13452 if (tid == TID_UINT16 || tid == TID_INT16) {
13453 arg[0] = arg[2];
13454 arg[1] = arg[3];
13455 }
13456 }
13457
13458 if (flags & RPC_IN) {
13459 int arg_size = 0;
13460
13461 if (bpointer)
13462 arg_size = rpc_tid_size(tid);
13463 else
13464 arg_size = rpc_tid_size(arg_type);
13465
13466 /* for strings, the argument size depends on the string length */
13467 if (tid == TID_STRING || tid == TID_LINK) {
13468 arg_size = 1 + strlen((char *) *((char **) arg));
13469 }
13470
13471 /* for varibale length arrays, the size is given by
13472 the next parameter on the stack */
13473 if (flags & RPC_VARARRAY) {
13474 //va_list aptmp;
13476 //va_copy(aptmp, ap);
13477
13478 //char arg_tmp[8];
13479 //rpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
13480
13481 const char* arg_tmp = args[i+1];
13482
13483 /* for (RPC_IN+RPC_OUT) parameters, size argument is a pointer */
13484 if (flags & RPC_OUT)
13485 arg_size = *((INT *) *((void **) arg_tmp));
13486 else
13487 arg_size = *((INT *) arg_tmp);
13488
13489 *((INT *) param_ptr) = ALIGN8(arg_size);
13490 param_ptr += ALIGN8(sizeof(INT));
13491
13492 //va_end(aptmp);
13493 }
13494
13495 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13496 arg_size = rl.param[i].n;
13497
13498 /* always align parameter size */
13499 int param_size = ALIGN8(arg_size);
13500
13501 {
13502 size_t param_offset = (char *) param_ptr - (char *)(*nc);
13503
13504 if (param_offset + param_size + 16 > buf_size) {
13505 size_t new_size = param_offset + param_size + 1024;
13506 //printf("resize nc %zu to %zu\n", buf_size, new_size);
13507 buf = (char *) realloc(buf, new_size);
13508 assert(buf);
13509 buf_size = new_size;
13510 (*nc) = (NET_COMMAND*) buf;
13511 param_ptr = buf + param_offset;
13512 }
13513 }
13514
13515 if (bpointer) {
13516 if (debug) {
13517 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);
13518 }
13519 memcpy(param_ptr, (void *) *((void **) arg), arg_size);
13520 } else if (tid == TID_FLOAT) {
13521 if (debug) {
13522 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);
13523 }
13524 /* floats are passed as doubles on most systems */
13525 *((float *) param_ptr) = (float) *((double *) arg);
13526 } else {
13527 if (debug) {
13528 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);
13529 }
13530 memcpy(param_ptr, arg, arg_size);
13531 }
13532
13533 param_ptr += param_size;
13534 }
13535 }
13536
13537 (*nc)->header.param_size = (POINTER_T) param_ptr - (POINTER_T) (*nc)->param;
13538
13539 if (debug)
13540 printf("encode rpc_id %d \"%s\" buf_size %d, param_size %d\n", rl.id, rl.name, (int)buf_size, (*nc)->header.param_size);
13541}
#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:12974
#define RPC_IN
Definition midas.h:1563
#define MAX_RPC_PARAMS
Definition midas.h:1579
#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 13616 of file midas.cxx.

13617{
13618 //printf("rpc_call_encode_cxx!\n");
13619
13620 bool debug = false;
13621
13622 //if (rl.id == RPC_TEST2)
13623 // debug = true;
13624
13625 //if (rl.id == RPC_TEST2_CXX)
13626 // debug = true;
13627
13628 if (debug) {
13629 printf("encode rpc_id %d \"%s\"\n", rl.id, rl.name);
13630 for (int i=0; rl.param[i].tid != 0; i++) {
13631 int tid = rl.param[i].tid;
13632 int flags = rl.param[i].flags;
13633 int n = rl.param[i].n;
13634 printf("param %2d, tid %2d, flags 0x%02x, n %3d\n", i, tid, flags, n);
13635 }
13636 }
13637
13638 char args[MAX_RPC_PARAMS][sizeof(char*)];
13639
13640 for (int i=0; rl.param[i].tid != 0; i++) {
13641 int tid = rl.param[i].tid;
13642 int flags = rl.param[i].flags;
13643 int arg_type = 0;
13644
13645 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13646 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13647 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13648
13649 if (bpointer)
13650 arg_type = TID_ARRAY;
13651 else
13652 arg_type = tid;
13653
13654 /* floats are passed as doubles, at least under NT */
13655 if (tid == TID_FLOAT && !bpointer)
13656 arg_type = TID_DOUBLE;
13657
13658 //printf("arg %d, tid %d, flags 0x%x, arg_type %d, bpointer %d\n", i, tid, flags, arg_type, bpointer);
13659
13660 rpc_va_arg(&ap, arg_type, args[i]);
13661 }
13662
13663 size_t buf_size = sizeof(NET_COMMAND) + 4 * 1024;
13664 char* buf = (char *)malloc(buf_size);
13665 assert(buf);
13666
13667 (*nc) = (NET_COMMAND*) buf;
13668
13669 /* find out if we are on a big endian system */
13670 bool bbig = ((rpc_get_hw_type() & DRI_BIG_ENDIAN) > 0);
13671
13672 char* param_ptr = (*nc)->param;
13673
13674 for (int i=0; rl.param[i].tid != 0; i++) {
13675 int tid = rl.param[i].tid;
13676 int flags = rl.param[i].flags;
13677 int arg_type = 0;
13678
13679 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13680 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13681 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13682
13683 if (bpointer)
13684 arg_type = TID_ARRAY;
13685 else
13686 arg_type = tid;
13687
13688 /* floats are passed as doubles, at least under NT */
13689 if (tid == TID_FLOAT && !bpointer)
13690 arg_type = TID_DOUBLE;
13691
13692 /* get pointer to argument */
13693 //char arg[8];
13694 //rpc_va_arg(&ap, arg_type, arg);
13695
13696 char* arg = args[i];
13697
13698 /* shift 1- and 2-byte parameters to the LSB on big endian systems */
13699 if (bbig) {
13700 if (tid == TID_UINT8 || tid == TID_CHAR || tid == TID_INT8) {
13701 arg[0] = arg[3];
13702 }
13703 if (tid == TID_UINT16 || tid == TID_INT16) {
13704 arg[0] = arg[2];
13705 arg[1] = arg[3];
13706 }
13707 }
13708
13709 if (flags & RPC_IN) {
13710 int arg_size = 0;
13711
13712 if (bpointer)
13713 arg_size = rpc_tid_size(tid);
13714 else
13715 arg_size = rpc_tid_size(arg_type);
13716
13717 void* parg = (void *) *((void **) arg);
13718
13719 /* for strings, the argument size depends on the string length */
13720 if ((tid == TID_STRING) && (flags & RPC_CXX)) {
13721 std::string* s = (std::string*)parg;
13722 arg_size = 1 + s->length();
13723 parg = (void*)s->c_str();
13724 bpointer = TRUE;
13725 //printf("STRING %p, len %zu, [%s]\n", s, s->length(), s->c_str());
13726 } else if (tid == TID_STRING || tid == TID_LINK) {
13727 arg_size = 1 + strlen((char *) *((char **) arg));
13728 }
13729
13730 /* for varibale length arrays, the size is given by
13731 the next parameter on the stack */
13732 if (flags & RPC_VARARRAY) {
13733 //va_list aptmp;
13735 //va_copy(aptmp, ap);
13736
13737 //char arg_tmp[8];
13738 //rpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
13739
13740 if (flags & RPC_CXX) {
13741 std::vector<char>* pv = (std::vector<char>*)parg;
13742 arg_size = pv->size();
13743 parg = (void*)pv->data();
13744 bpointer = TRUE;
13745 //printf("VECTOR %p, size %zu\n", pv, pv->size());
13746
13747 *((INT *) param_ptr) = arg_size; // NB: for std:vector<char> data, pass true data size. it is safe because decoder always aligns it themselves.
13748
13749 } else {
13750 const char* arg_tmp = args[i+1];
13751
13752 /* for (RPC_IN+RPC_OUT) parameters, size argument is a pointer */
13753 if (flags & RPC_OUT) {
13754 arg_size = *((INT *) *((void **) arg_tmp));
13755 } else {
13756 arg_size = *((INT *) arg_tmp);
13757 }
13758
13759 *((INT *) param_ptr) = ALIGN8(arg_size);
13760 }
13761
13762 param_ptr += ALIGN8(sizeof(INT));
13763
13764 //va_end(aptmp);
13765 }
13766
13767 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13768 arg_size = rl.param[i].n;
13769
13770 /* always align parameter size */
13771 int param_size = ALIGN8(arg_size);
13772
13773 {
13774 size_t param_offset = (char *) param_ptr - (char *)(*nc);
13775
13776 if (param_offset + param_size + 16 > buf_size) {
13777 size_t new_size = param_offset + param_size + 1024;
13778 //printf("resize nc %zu to %zu\n", buf_size, new_size);
13779 buf = (char *) realloc(buf, new_size);
13780 assert(buf);
13781 buf_size = new_size;
13782 (*nc) = (NET_COMMAND*) buf;
13783 param_ptr = buf + param_offset;
13784 }
13785 }
13786
13787 if (bpointer) {
13788 if (debug) {
13789 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);
13790 }
13791 memcpy(param_ptr, parg, arg_size);
13792 } else if (tid == TID_FLOAT) {
13793 if (debug) {
13794 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);
13795 }
13796 /* floats are passed as doubles on most systems */
13797 *((float *) param_ptr) = (float) *((double *) arg);
13798 } else {
13799 if (debug) {
13800 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);
13801 }
13802 memcpy(param_ptr, arg, arg_size);
13803 }
13804
13805 param_ptr += param_size;
13806 }
13807 }
13808
13809 (*nc)->header.param_size = (POINTER_T) param_ptr - (POINTER_T) (*nc)->param;
13810
13811 if (debug)
13812 printf("encode rpc_id %d \"%s\" buf_size %d, param_size %d\n", rl.id, rl.name, (int)buf_size, (*nc)->header.param_size);
13813}
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 16632 of file midas.cxx.

16643{
16644 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
16645
16647 return RPC_SUCCESS;
16648
16649 if (strcmp(hostname, "localhost") == 0)
16650 return RPC_SUCCESS;
16651
16652 if (strcmp(hostname, "localhost.localdomain") == 0)
16653 return RPC_SUCCESS;
16654
16655 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
16656 return RPC_SUCCESS;
16657
16658 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
16659 return RPC_SUCCESS;
16660
16662
16663 gAllowedHostsMutex.lock();
16664
16665 for (const auto& h: gAllowedHosts) {
16666 if (h == hostname) {
16668 break;
16669 }
16670 }
16671
16672 gAllowedHostsMutex.unlock();
16673
16674 //if (status != RPC_SUCCESS)
16675 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
16676
16677 return status;
16678}
#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 17652 of file midas.cxx.

17670{
17671 INT status;
17672 NET_COMMAND nc;
17673 fd_set readfds;
17674 struct timeval timeout;
17675
17676 //printf("rpc_check_channels!\n");
17677
17678 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
17679 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
17681 if (sa == NULL)
17682 continue;
17683
17684 if (sa->watchdog_timeout == 0) {
17685 continue;
17686 }
17687
17688 DWORD elapsed = ss_millitime() - sa->last_activity;
17689
17690 //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
17691
17692 if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
17693
17694 //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
17695
17696 /* send a watchdog message */
17698 nc.header.param_size = 0;
17699
17700 int convert_flags = sa->convert_flags;
17701 if (convert_flags) {
17704 }
17705
17706 /* send the header to the client */
17707 int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
17708
17709 if (i < 0) {
17710 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
17711 sa->prog_name.c_str(),
17712 sa->host_name.c_str(),
17713 sa->watchdog_timeout / 1000,
17714 i);
17715
17716 /* disconnect from experiment */
17717 if (rpc_is_mserver()) {
17719 return RPC_NET_ERROR;
17720 }
17721
17722 sa->close();
17723 return RPC_NET_ERROR;
17724 }
17725
17726 DWORD timeout_end_ms = ss_millitime() + sa->watchdog_timeout;
17727
17728 while (1) {
17729 FD_ZERO(&readfds);
17730 FD_SET(sa->send_sock, &readfds);
17731 FD_SET(sa->recv_sock, &readfds);
17732
17733 timeout.tv_sec = 1;
17734 timeout.tv_usec = 0;
17735
17736 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
17737
17738 DWORD now = ss_millitime();
17739
17740 //printf("waiting for reply: %d %d, diff %d, select() status %d\n", now, timeout_end_ms, timeout_end_ms - now, status);
17741
17742 if (now > timeout_end_ms) // timeout
17743 break;
17744
17745 if (status > 0) // select has something to read
17746 break;
17747
17748 // select() returned 0, timeout
17749 // select() returned -1, error, likely EAGAIN or EINTR
17750
17753 }
17754
17755 if (!FD_ISSET(sa->send_sock, &readfds) &&
17756 !FD_ISSET(sa->recv_sock, &readfds)) {
17757
17758 cm_msg(MERROR, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
17759 sa->prog_name.c_str(),
17760 sa->host_name.c_str(),
17761 sa->watchdog_timeout / 1000);
17762
17763 /* disconnect from experiment */
17764 if (rpc_is_mserver()) {
17766 return RPC_NET_ERROR;
17767 }
17768
17769 sa->close();
17770 return RPC_NET_ERROR;
17771 }
17772
17773 /* receive result on send socket */
17774 if (FD_ISSET(sa->send_sock, &readfds)) {
17775 i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
17776 if (i <= 0) {
17777 cm_msg(MERROR, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
17778 sa->prog_name.c_str(),
17779 sa->host_name.c_str(),
17780 sa->watchdog_timeout / 1000,
17781 i);
17782
17783 /* disconnect from experiment */
17784 if (rpc_is_mserver()) {
17786 return RPC_NET_ERROR;
17787 }
17788
17789 sa->close();
17790 return RPC_NET_ERROR;
17791 }
17792 }
17793 }
17794 }
17795 }
17796
17797 return RPC_SUCCESS;
17798}
INT cm_periodic_tasks()
Definition midas.cxx:5597
INT cm_disconnect_experiment(void)
Definition midas.cxx:2862
#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:881
bool rpc_is_mserver(void)
Definition midas.cxx:12958
#define RPC_OUTGOING
Definition midas.h:1568
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 16578 of file midas.cxx.

16594{
16595 gAllowedHostsMutex.lock();
16596 gAllowedHosts.clear();
16597 gAllowedHostsEnabled = false;
16598 gAllowedHostsMutex.unlock();
16599 return RPC_SUCCESS;
16600}
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 16966 of file midas.cxx.

16987{
16988 INT i, status;
16989 INT client_hw_type = 0, hw_type;
16990 std::string client_program;
16991 std::string host_name;
16992 INT convert_flags;
16993 char net_buffer[256], *p;
16994
16995 int sock = accept(lsock, NULL, NULL);
16996
16997 if (sock == -1)
16998 return RPC_NET_ERROR;
16999
17000 /* check access control list */
17003
17004 if (status != RPC_SUCCESS) {
17005 ss_socket_close(&sock);
17006 return RPC_NET_ERROR;
17007 }
17008 }
17009
17010 host_name = "(unknown)";
17011 client_program = "(unknown)";
17012
17013 /* receive string with timeout */
17014 i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
17015 if (i <= 0) {
17016 ss_socket_close(&sock);
17017 return RPC_NET_ERROR;
17018 }
17019
17020 /* get remote computer info */
17021 p = strtok(net_buffer, " ");
17022 if (p != NULL) {
17023 client_hw_type = atoi(p);
17024 p = strtok(NULL, " ");
17025 }
17026 if (p != NULL) {
17027 //version = atoi(p);
17028 p = strtok(NULL, " ");
17029 }
17030 if (p != NULL) {
17031 client_program = p;
17032 p = strtok(NULL, " ");
17033 }
17034 if (p != NULL) {
17035 host_name = p;
17036 p = strtok(NULL, " ");
17037 }
17038
17039 //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
17040
17042
17043 /* save information in _server_acception structure */
17044 sa->recv_sock = sock;
17045 sa->send_sock = 0;
17046 sa->event_sock = 0;
17047 sa->remote_hw_type = client_hw_type;
17048 sa->host_name = host_name;
17049 sa->prog_name = client_program;
17051 sa->watchdog_timeout = 0;
17052 sa->is_mserver = FALSE;
17053
17054 /* send my own computer id */
17055 hw_type = rpc_get_hw_type();
17056 std::string str = msprintf("%d %s", hw_type, cm_get_version());
17057 status = send(sock, str.c_str(), str.length() + 1, 0);
17058 if (status != (INT) str.length() + 1)
17059 return RPC_NET_ERROR;
17060
17061 rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
17062 sa->convert_flags = convert_flags;
17063
17065
17066 return RPC_SUCCESS;
17067}
const char * cm_get_version()
Definition midas.cxx:1492
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:11723
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition midas.cxx:11658
static INT rpc_socket_check_allowed_host(int sock)
Definition midas.cxx:16681
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 13935 of file midas.cxx.

13960{
13962
13963 if (!c) {
13964 cm_msg(MERROR, "rpc_client_call", "invalid rpc connection handle %d", hConn);
13965 return RPC_NO_CONNECTION;
13966 }
13967
13968 //printf("rpc_client_call: handle %d, connection: ", hConn);
13969 //c->print();
13970 //printf("\n");
13971
13972 INT i, status;
13973
13974 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13975 routine_id &= ~RPC_NO_REPLY;
13976
13977 //if (rpc_no_reply)
13978 // printf("rpc_client_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13979
13980 // make local copy of the client name just in case _client_connection is erased by another thread
13981
13982 /* find rpc_index */
13983
13984 RPC_LIST rpc_entry;
13985 bool rpc_cxx = false;
13986
13987 status = rpc_find_rpc(routine_id, &rpc_entry, &rpc_cxx);
13988
13989 if (status != RPC_SUCCESS) {
13990 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);
13991 c->mutex.unlock();
13992 return RPC_INVALID_ID;
13993 }
13994
13995 const char *rpc_name = rpc_entry.name;
13996
13997 NET_COMMAND *nc = NULL;
13998
13999 /* examine variable argument list and convert it to parameter array */
14000 va_list ap;
14001 va_start(ap, routine_id);
14002
14003 if (rpc_cxx)
14004 rpc_call_encode_cxx(ap, rpc_entry, &nc);
14005 else
14006 rpc_call_encode(ap, rpc_entry, &nc);
14007
14008 va_end(ap);
14009
14010 nc->header.routine_id = routine_id;
14011
14012 if (rpc_no_reply)
14014
14015 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
14016
14017 /* in FAST TCP mode, only send call and return immediately */
14018 if (rpc_no_reply) {
14019 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
14020
14021 if (i != send_size) {
14022 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);
14023 free(nc);
14024 c->mutex.unlock();
14025 return RPC_NET_ERROR;
14026 }
14027
14028 free(nc);
14029
14030 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN) {
14031 //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);
14032 //c->print();
14033 //printf("\n");
14034 c->close_locked();
14035 }
14036
14037 c->mutex.unlock();
14038 return RPC_SUCCESS;
14039 }
14040
14041 /* in TCP mode, send and wait for reply on send socket */
14042 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
14043 if (i != send_size) {
14044 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);
14045 c->mutex.unlock();
14046 return RPC_NET_ERROR;
14047 }
14048
14049 free(nc);
14050 nc = NULL;
14051
14052 bool restore_watchdog_timeout = false;
14053 BOOL watchdog_call;
14054 DWORD watchdog_timeout;
14055 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
14056
14057 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, c->rpc_timeout);
14058
14059 if (c->rpc_timeout >= (int) watchdog_timeout) {
14060 restore_watchdog_timeout = true;
14061 cm_set_watchdog_params(watchdog_call, c->rpc_timeout + 1000);
14062 }
14063
14064 DWORD rpc_status = 0;
14065 DWORD buf_size = 0;
14066 char* buf = NULL;
14067
14068 /* receive result on send socket */
14069 status = ss_recv_net_command(c->send_sock, &rpc_status, &buf_size, &buf, c->rpc_timeout);
14070
14071 if (restore_watchdog_timeout) {
14072 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
14073 }
14074
14075 if (status == SS_TIMEOUT) {
14076 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);
14077 if (buf)
14078 free(buf);
14079 c->mutex.unlock();
14080 return RPC_TIMEOUT;
14081 }
14082
14083 if (status != SS_SUCCESS) {
14084 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);
14085 if (buf)
14086 free(buf);
14087 c->mutex.unlock();
14088 return RPC_NET_ERROR;
14089 }
14090
14091 c->mutex.unlock();
14092
14093 if (rpc_status == RPC_INVALID_ID) {
14094 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);
14095 if (buf)
14096 free(buf);
14097 return rpc_status;
14098 }
14099
14100 /* extract result variables and place it to argument list */
14101
14102 va_start(ap, routine_id);
14103
14104 if (rpc_cxx)
14105 status = rpc_call_decode_cxx(ap, rpc_entry, buf, buf_size);
14106 else
14107 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
14108
14109 if (status != RPC_SUCCESS) {
14110 rpc_status = status;
14111 }
14112
14113 va_end(ap);
14114
14115 if (buf)
14116 free(buf);
14117 buf = NULL;
14118 buf_size = 0;
14119
14120 return rpc_status;
14121}
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3299
#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:12752
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 12410 of file midas.cxx.

12418{
12419#if 0
12420 for (i = 0; i < MAX_RPC_CONNECTION; i++)
12421 if (_client_connection[i].send_sock != 0)
12422 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);
12423#endif
12424
12425 std::lock_guard<std::mutex> guard(_client_connections_mutex);
12426
12427 /* check for broken connections */
12428 for (unsigned i = 0; i < _client_connections.size(); i++) {
12430 if (c && c->connected) {
12431 std::lock_guard<std::mutex> cguard(c->mutex);
12432
12433 if (!c->connected) {
12434 // implicit unlock
12435 continue;
12436 }
12437
12438 //printf("rpc_client_check: connection %d: ", i);
12439 //c->print();
12440 //printf("\n");
12441
12442 int ok = 0;
12443
12444 fd_set readfds;
12445 FD_ZERO(&readfds);
12446 FD_SET(c->send_sock, &readfds);
12447
12448 struct timeval timeout;
12449 timeout.tv_sec = 0;
12450 timeout.tv_usec = 0;
12451
12452 int status;
12453
12454#ifdef OS_WINNT
12455 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12456#else
12457 do {
12458 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12459 } while (status == -1 && errno == EINTR); /* dont return if an alarm signal was cought */
12460#endif
12461
12462 if (!FD_ISSET(c->send_sock, &readfds)) {
12463 // implicit unlock
12464 continue;
12465 }
12466
12467 char buffer[64];
12468
12469 status = recv(c->send_sock, (char *) buffer, sizeof(buffer), MSG_PEEK);
12470 //printf("recv %d status %d, errno %d (%s)\n", sock, status, errno, strerror(errno));
12471
12472 if (status < 0) {
12473#ifndef OS_WINNT
12474 if (errno == EAGAIN) { // still connected
12475 ok = 1;
12476 } else
12477#endif
12478 {
12479 // connection error
12480 cm_msg(MERROR, "rpc_client_check",
12481 "RPC client connection to \"%s\" on host \"%s\" is broken, recv() errno %d (%s)",
12482 c->client_name.c_str(),
12483 c->host_name.c_str(),
12484 errno, strerror(errno));
12485 ok = 0;
12486 }
12487 } else if (status == 0) {
12488 // connection closed by remote end without sending an EXIT message
12489 // this can happen if the remote end has crashed, so this message
12490 // is still necessary as a useful diagnostic for unexpected crashes
12491 // of midas programs. K.O.
12492 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());
12493 ok = 0;
12494 } else {
12495 // read some data
12496 ok = 1;
12497 if (equal_ustring(buffer, "EXIT")) {
12498 /* normal exit */
12499 ok = 0;
12500 }
12501 }
12502
12503 if (!ok) {
12504 //printf("rpc_client_check: closing connection %d: ", i);
12505 //c->print();
12506 //printf("\n");
12507
12508 // connection lost, close the socket
12509 c->close_locked();
12510 }
12511
12512 // implicit unlock
12513 }
12514 }
12515
12516 // implicit unlock of _client_connections_mutex
12517}
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3780
static std::mutex _client_connections_mutex
Definition midas.cxx:11643
static std::vector< RPC_CLIENT_CONNECTION * > _client_connections
Definition midas.cxx:11644
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 12152 of file midas.cxx.

12175{
12176 INT i, status;
12177 bool debug = false;
12178
12179 /* check if cm_connect_experiment was called */
12180 if (_client_name.length() == 0) {
12181 cm_msg(MERROR, "rpc_client_connect", "cm_connect_experiment/rpc_set_name not called");
12182 return RPC_NOT_REGISTERED;
12183 }
12184
12185 /* refuse connection to port 0 */
12186 if (port == 0) {
12187 cm_msg(MERROR, "rpc_client_connect", "invalid port %d", port);
12188 return RPC_NET_ERROR;
12189 }
12190
12191 RPC_CLIENT_CONNECTION* c = NULL;
12192
12193 static std::mutex gHostnameMutex;
12194
12195 {
12196 std::lock_guard<std::mutex> guard(_client_connections_mutex);
12197
12198 if (debug) {
12199 printf("rpc_client_connect: host \"%s\", port %d, client \"%s\"\n", host_name, port, client_name);
12200 for (size_t i = 0; i < _client_connections.size(); i++) {
12201 if (_client_connections[i]) {
12202 printf("client connection %d: ", (int)i);
12203 _client_connections[i]->print();
12204 printf("\n");
12205 }
12206 }
12207 }
12208
12209 // slot with index 0 is not used, fill it with a NULL
12210
12211 if (_client_connections.empty()) {
12212 _client_connections.push_back(NULL);
12213 }
12214
12215 bool hostname_locked = false;
12216
12217 /* check if connection already exists */
12218 for (size_t i = 1; i < _client_connections.size(); i++) {
12220 if (c && c->connected) {
12221
12222 if (!hostname_locked) {
12223 gHostnameMutex.lock();
12224 hostname_locked = true;
12225 }
12226
12227 if ((c->host_name == host_name) && (c->port == port)) {
12228 // NB: we must release the hostname lock before taking
12229 // c->mutex to avoid a locking order inversion deadlock:
12230 // later on we lock the hostname mutex while holding the c->mutex
12231 gHostnameMutex.unlock();
12232 hostname_locked = false;
12233 std::lock_guard<std::mutex> cguard(c->mutex);
12234 // check if socket is still connected
12235 if (c->connected) {
12236 // found connection slot with matching hostname and port number
12237 status = ss_socket_wait(c->send_sock, 0);
12238 if (status == SS_TIMEOUT) { // yes, still connected and empty
12239 // so reuse it connection
12240 *hConnection = c->index;
12241 if (debug) {
12242 printf("already connected: ");
12243 c->print();
12244 printf("\n");
12245 }
12246 // implicit unlock of c->mutex
12247 // gHostnameLock is not locked here
12248 return RPC_SUCCESS;
12249 }
12250 //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);
12251 c->close_locked();
12252 }
12253 // implicit unlock of c->mutex
12254 }
12255 }
12256 }
12257
12258 if (hostname_locked) {
12259 gHostnameMutex.unlock();
12260 hostname_locked = false;
12261 }
12262
12263 // only start reusing connections once we have
12264 // a good number of slots allocated.
12265 if (_client_connections.size() > 10) {
12266 static int last_reused = 0;
12267
12268 int size = _client_connections.size();
12269 for (int j = 1; j < size; j++) {
12270 int i = (last_reused + j) % size;
12271 if (_client_connections[i] && !_client_connections[i]->connected) {
12273 if (debug) {
12274 printf("last reused %d, reusing slot %d: ", last_reused, (int)i);
12275 c->print();
12276 printf("\n");
12277 }
12278 last_reused = i;
12279 break;
12280 }
12281 }
12282 }
12283
12284 // no slots to reuse, allocate a new slot.
12285 if (!c) {
12287
12288 // if empty slot not found, add to end of array
12289 c->index = _client_connections.size();
12290 _client_connections.push_back(c);
12291
12292 if (debug) {
12293 printf("new connection appended to array: ");
12294 c->print();
12295 printf("\n");
12296 }
12297 }
12298
12299 c->mutex.lock();
12300 c->connected = true; // rpc_client_connect() in another thread may try to grab this slot
12301
12302 // done with the array of connections
12303 // implicit unlock of _client_connections_mutex
12304 }
12305
12306 // locked connection slot for new connection
12307 assert(c != NULL);
12308
12309 std::string errmsg;
12310
12311 /* create a new socket for connecting to remote server */
12312 status = ss_socket_connect_tcp(host_name, port, &c->send_sock, &errmsg);
12313 if (status != SS_SUCCESS) {
12314 cm_msg(MERROR, "rpc_client_connect", "cannot connect to \"%s\" port %d: %s", host_name, port, errmsg.c_str());
12315 c->mutex.unlock();
12316 return RPC_NET_ERROR;
12317 }
12318
12319 gHostnameMutex.lock();
12320
12321 c->host_name = host_name;
12322 c->port = port;
12323
12324 gHostnameMutex.unlock();
12325
12326 c->client_name = client_name;
12327 c->rpc_timeout = DEFAULT_RPC_TIMEOUT;
12328
12329 /* set TCP_NODELAY option for better performance */
12330 i = 1;
12331 setsockopt(c->send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
12332
12333 /* send local computer info */
12334 std::string local_prog_name = rpc_get_name();
12335 std::string local_host_name = ss_gethostname();
12336
12337 int hw_type = rpc_get_hw_type();
12338
12339 std::string cstr = msprintf("%d %s %s %s", hw_type, cm_get_version(), local_prog_name.c_str(), local_host_name.c_str());
12340
12341 int size = cstr.length() + 1;
12342 i = send(c->send_sock, cstr.c_str(), size, 0);
12343 if (i < 0 || i != size) {
12344 cm_msg(MERROR, "rpc_client_connect", "cannot send %d bytes, send() returned %d, errno %d (%s)", size, i, errno, strerror(errno));
12345 c->mutex.unlock();
12346 return RPC_NET_ERROR;
12347 }
12348
12349 bool restore_watchdog_timeout = false;
12350 BOOL watchdog_call;
12351 DWORD watchdog_timeout;
12352 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
12353
12354 //printf("watchdog timeout: %d, rpc_connect_timeout: %d\n", watchdog_timeout, _rpc_connect_timeout);
12355
12356 if (_rpc_connect_timeout >= (int) watchdog_timeout) {
12357 restore_watchdog_timeout = true;
12358 cm_set_watchdog_params(watchdog_call, _rpc_connect_timeout + 1000);
12359 }
12360
12361 char str[256];
12362
12363 /* receive remote computer info */
12364 i = recv_string(c->send_sock, str, sizeof(str), _rpc_connect_timeout);
12365
12366 if (restore_watchdog_timeout) {
12367 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
12368 }
12369
12370 if (i <= 0) {
12371 cm_msg(MERROR, "rpc_client_connect", "timeout waiting for server reply");
12372 c->close_locked();
12373 c->mutex.unlock();
12374 return RPC_NET_ERROR;
12375 }
12376
12377 int remote_hw_type = 0;
12378 char remote_version[32];
12379 remote_version[0] = 0;
12380 sscanf(str, "%d %s", &remote_hw_type, remote_version);
12381
12382 c->remote_hw_type = remote_hw_type;
12383
12384 /* print warning if version patch level doesn't agree */
12385 char v1[32];
12386 mstrlcpy(v1, remote_version, sizeof(v1));
12387 if (strchr(v1, '.'))
12388 if (strchr(strchr(v1, '.') + 1, '.'))
12389 *strchr(strchr(v1, '.') + 1, '.') = 0;
12390
12391 mstrlcpy(str, cm_get_version(), sizeof(str));
12392 if (strchr(str, '.'))
12393 if (strchr(strchr(str, '.') + 1, '.'))
12394 *strchr(strchr(str, '.') + 1, '.') = 0;
12395
12396 if (strcmp(v1, str) != 0) {
12397 cm_msg(MERROR, "rpc_client_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", remote_version, cm_get_version());
12398 }
12399
12400 c->connected = true;
12401
12402 *hConnection = c->index;
12403
12404 c->mutex.unlock();
12405
12406 return RPC_SUCCESS;
12407}
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:13224
static std::string _client_name
Definition midas.cxx:1475
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 12816 of file midas.cxx.

12834{
12835 /* notify server about exit */
12836
12837 /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12838
12840
12841 return RPC_SUCCESS;
12842}
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13935
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 12085 of file midas.cxx.

12093{
12094 INT status = 0;
12095 char net_buffer[256];
12096
12097 int n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
12098 if (n <= 0)
12099 return SS_ABORT;
12100
12101 NET_COMMAND *nc = (NET_COMMAND *) net_buffer;
12102
12103 if (nc->header.routine_id == MSG_ODB) {
12104 status = handle_msg_odb(n, nc);
12105 } else if (nc->header.routine_id == MSG_WATCHDOG) {
12106 nc->header.routine_id = 1;
12107 nc->header.param_size = 0;
12108 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
12110 } else if (nc->header.routine_id == MSG_BM) {
12111 fd_set readfds;
12112 struct timeval timeout;
12113
12114 //printf("rpc_client_dispatch: received MSG_BM!\n");
12115
12116 /* receive further messages to empty TCP queue */
12117 do {
12118 FD_ZERO(&readfds);
12119 FD_SET(sock, &readfds);
12120
12121 timeout.tv_sec = 0;
12122 timeout.tv_usec = 0;
12123
12124 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12125
12126 if (FD_ISSET(sock, &readfds)) {
12127 n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
12128 if (n <= 0)
12129 return SS_ABORT;
12130
12131 if (nc->header.routine_id == MSG_ODB) {
12132 status = handle_msg_odb(n, nc);
12133 } else if (nc->header.routine_id == MSG_WATCHDOG) {
12134 nc->header.routine_id = 1;
12135 nc->header.param_size = 0;
12136 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
12138 }
12139 }
12140
12141 } while (FD_ISSET(sock, &readfds));
12142
12143 /* poll event from server */
12145 }
12146
12147 return status;
12148}
INT bm_poll_event()
Definition midas.cxx:11274
#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:12071
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 11846 of file midas.cxx.

11874{
11875 /* convert array */
11876 if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11877 int single_size = rpc_tid_size(tid);
11878 /* don't convert TID_ARRAY & TID_STRUCT */
11879 if (single_size == 0)
11880 return;
11881
11882 int n = total_size / single_size;
11883
11884 for (int i = 0; i < n; i++) {
11885 char* p = (char *) data + (i * single_size);
11886 rpc_convert_single(p, tid, flags, convert_flags);
11887 }
11888 } else {
11889 rpc_convert_single(data, tid, flags, convert_flags);
11890 }
11891}
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 11821 of file midas.cxx.

11821 {
11822
11823 if (convert_flags & CF_ENDIAN) {
11824 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11825 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11826 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11827 }
11828
11829 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11830 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11831 if (tid == TID_FLOAT)
11832 rpc_ieee2vax_float((float *) data);
11833 if (tid == TID_DOUBLE)
11834 rpc_ieee2vax_double((double *) data);
11835 }
11836
11837 if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11838 ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11839 if (tid == TID_FLOAT)
11840 rpc_vax2ieee_float((float *) data);
11841 if (tid == TID_DOUBLE)
11842 rpc_vax2ieee_double((double *) data);
11843 }
11844}
#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:11766
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11751
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11801
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11782
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 13301 of file midas.cxx.

13315{
13316 va_list argptr;
13317 char str[1000];
13318
13319 if (_debug_mode) {
13320 va_start(argptr, format);
13321 vsprintf(str, (char *) format, argptr);
13322 va_end(argptr);
13323
13324 if (_debug_print) {
13325 strcat(str, "\n");
13327 } else
13328 puts(str);
13329 }
13330}
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 12010 of file midas.cxx.

12027{
12028 rpc_list_mutex.lock();
12029 rpc_list.clear();
12030 rpc_list_mutex.unlock();
12031
12032 return RPC_SUCCESS;
12033}
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11713
static std::mutex rpc_list_mutex
Definition midas.cxx:11714
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 15512 of file midas.cxx.

15539{
15540 INT status;
15541
15542 bool debug = false;
15543
15544 /* extract pointer array to parameters */
15545 NET_COMMAND* nc_in = (NET_COMMAND *) buffer;
15546
15547 /* convert header format (byte swapping) */
15548 if (convert_flags) {
15549 rpc_convert_single(&nc_in->header.routine_id, TID_UINT32, 0, convert_flags);
15550 rpc_convert_single(&nc_in->header.param_size, TID_UINT32, 0, convert_flags);
15551 }
15552
15553 //if (nc_in->header.routine_id & RPC_NO_REPLY) {
15554 // printf("rpc_execute: routine_id %d, RPC_NO_REPLY\n", (int)(nc_in->header.routine_id & ~RPC_NO_REPLY));
15555 //}
15556
15557 /* no result return as requested */
15558 if (nc_in->header.routine_id & RPC_NO_REPLY)
15559 sock = 0;
15560
15561 int routine_id = nc_in->header.routine_id & ~RPC_NO_REPLY;
15562
15563 assert(xroutine_id == routine_id);
15564
15565#if 0
15566 if (routine_id == RPC_TEST2)
15567 debug = true;
15568
15569 if (routine_id == RPC_TEST2_CXX)
15570 debug = true;
15571
15572 if (routine_id == RPC_TEST3_CXX)
15573 debug = true;
15574
15575 if (routine_id == RPC_TEST4_CXX)
15576 debug = true;
15577#endif
15578
15579 /* find entry in rpc_list */
15580
15581 char* in_param_ptr = (char*)nc_in->param;
15582
15583 if (debug)
15584 printf("rpc_execute_cxx: routine_id %d, name \"%s\"\n", routine_id, rl.name);
15585
15586 void *prpc_param[MAX_RPC_PARAMS];
15587
15588 size_t in_param_size[MAX_RPC_PARAMS];
15589 size_t in_param_offset[MAX_RPC_PARAMS];
15590
15591 std::vector<RPE> params;
15592
15593 int nparams = 0;
15594 for (int i = 0; rl.param[i].tid != 0; i++) {
15595 nparams++;
15596 }
15597
15598 params.resize(nparams);
15599
15600 size_t in_offset = 0;
15601
15602 for (int i = 0; i < nparams; i++) {
15603 in_param_size[i] = 0;
15604 in_param_offset[i] = 0;
15605
15606 int tid = rl.param[i].tid;
15607 int flags = rl.param[i].flags;
15608
15609 if (flags & RPC_IN) {
15610 int arg_size = rpc_tid_size(tid);
15611
15612 if (tid == TID_STRING || tid == TID_LINK) {
15613 arg_size = 1 + strlen((char *) (in_param_ptr));
15614 }
15615
15616 if (flags & RPC_VARARRAY) {
15617 /* for arrays, the size is stored as a INT in front of the array */
15618 int arg_size_align8 = *((INT *) in_param_ptr);
15619 if (convert_flags)
15620 rpc_convert_single(&arg_size_align8, TID_INT32, 0, convert_flags);
15621 in_param_ptr += ALIGN8(sizeof(INT));
15622 in_offset += ALIGN8(sizeof(INT));
15623 if (flags & RPC_CXX) {
15624 /* for std::vector<char> data, it is the true length of the array */
15625 arg_size = arg_size_align8;
15626 } else {
15627 /* true size is stored in the next parameter */
15628 arg_size = *((INT *) (((char*)in_param_ptr) + ALIGN8(arg_size_align8))); // NB: this ALIGN8() is redundant with ALIGN8() in the RPC client *encoder*
15629 if (convert_flags)
15630 rpc_convert_single(&arg_size, TID_INT32, 0, convert_flags);
15631 }
15632 //printf("RPC_VARARRAY: arg_size %d %d\n", arg_size_align8, arg_size);
15633
15634 if (ALIGN8(arg_size_align8) != ALIGN8(arg_size)) {
15635 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);
15636 return RPC_INVALID_ID;
15637 }
15638 }
15639
15640 if (tid == TID_STRUCT) {
15641 arg_size = rl.param[i].n;
15642 }
15643
15644 int param_size = ALIGN8(arg_size);
15645
15646 in_param_size[i] = param_size;
15647 in_param_offset[i] = in_offset;
15648
15649 params[i].offset = in_offset;
15650 params[i].arg_size = arg_size;
15651 params[i].param_size = param_size;
15652
15653 /* convert data format */
15654 if (convert_flags) {
15655 if (flags & RPC_VARARRAY) {
15656 rpc_convert_data(in_param_ptr, tid, flags, param_size, convert_flags);
15657 } else {
15658 rpc_convert_data(in_param_ptr, tid, flags, rl.param[i].n * rpc_tid_size(tid), convert_flags);
15659 }
15660 }
15661
15662 in_param_ptr += param_size;
15663 in_offset += param_size;
15664 }
15665
15666 if (flags & RPC_OUT) {
15667 params[i].out_max_size = rpc_tid_size(tid);
15668
15669 if (flags & RPC_CXX) {
15670 params[i].out_max_size = 0; // no max size!
15671 } else if (flags & RPC_VARARRAY || tid == TID_STRING) {
15672
15673 /* save maximum array length from the value of the next argument.
15674 * this means RPC_OUT arrays and strings should always be passed like this:
15675 * rpc_call(..., array_ptr, array_max_size, ...); */
15676
15677 params[i].out_max_size_offset = in_offset;
15678
15679 INT max_size = *((INT *) in_param_ptr);
15680
15681 if (convert_flags)
15682 rpc_convert_single(&max_size, TID_INT32, 0, convert_flags);
15683
15684 params[i].out_max_size = max_size;
15685 }
15686
15687 if (rl.param[i].tid == TID_STRUCT) {
15688 params[i].out_max_size = rl.param[i].n;
15689 }
15690 }
15691
15692 if (flags & RPC_CXX) {
15693 if (tid == TID_STRING) {
15694 params[i].ps = new std::string;
15695 if (flags & RPC_IN) {
15696 *(params[i].ps) = (char*)nc_in->param + in_param_offset[i];
15697 //printf("STRING %d decode [%s]\n", i, (char*)nc_in->param + in_param_offset[i]);
15698 }
15699 prpc_param[i] = (void*) params[i].ps;
15700 } else if (tid == TID_ARRAY) {
15701 params[i].pv = new std::vector<char>;
15702 if (flags & RPC_IN) {
15703 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);
15704 //printf("VECTOR %d decode %zu bytes\n", i, params[i].pv->size());
15705 }
15706 prpc_param[i] = (void*) params[i].pv;
15707 } else {
15708 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);
15709 return RPC_INVALID_ID;
15710 }
15711 } else {
15712 if ((flags & RPC_IN) && (flags & RPC_OUT)) {
15713 params[i].pv = new std::vector<char>;
15714 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);
15715 size_t want_size = params[i].out_max_size;
15716 //printf("param %d size %zu want %zu\n", i, params[i].pv->size(), want_size);
15717 if (params[i].pv->size() < want_size)
15718 params[i].pv->resize(want_size);
15719 prpc_param[i] = params[i].pv->data();
15720 } else if (flags & RPC_IN) {
15721 prpc_param[i] = (char*)nc_in->param + in_param_offset[i];
15722 //printf("param %d input value %d [%s]\n", i, *(int*)prpc_param[i], (char*)prpc_param[i]);
15723 } else if (flags & RPC_OUT) {
15724 params[i].pv = new std::vector<char>;
15725 params[i].pv->resize(params[i].out_max_size);
15726 prpc_param[i] = params[i].pv->data();
15727 //printf("param %d size %zu\n", i, params[i].pv->size());
15728 }
15729 }
15730
15731 if (debug)
15732 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]);
15733 }
15734
15735 if (debug)
15736 printf("rpc_execute_cxx: nc_in size %d, in_offset %zu\n", nc_in->header.param_size, in_offset);
15737
15738 if (routine_id == RPC_TEST2) {
15739 bool ok = true;
15740
15741 ok &= in_param_offset[ 0] == 0; ok &= in_param_size[ 0] == 8; // int_in
15742 ok &= in_param_offset[ 1] == 0; ok &= in_param_size[ 1] == 0; // int_out
15743 ok &= in_param_offset[ 2] == 8; ok &= in_param_size[ 2] == 8; // &int_inout
15744 ok &= in_param_offset[ 3] == 16; ok &= in_param_size[ 3] == 16; // string_in
15745 ok &= in_param_offset[ 4] == 0; ok &= in_param_size[ 4] == 0; // string_out
15746 ok &= in_param_offset[ 5] == 32; ok &= in_param_size[ 5] == 8; // string_out size
15747 ok &= in_param_offset[ 6] == 0; ok &= in_param_size[ 6] == 0; // string2_out
15748 ok &= in_param_offset[ 7] == 40; ok &= in_param_size[ 7] == 8; // string2_out size
15749 ok &= in_param_offset[ 8] == 48; ok &= in_param_size[ 8] == 16; // string_inout
15750 ok &= in_param_offset[ 9] == 64; ok &= in_param_size[ 9] == 8; // string_inout size
15751 ok &= in_param_offset[10] == 72; ok &= in_param_size[10] == 72; // struct_in
15752 ok &= in_param_offset[11] == 0; ok &= in_param_size[11] == 0; // struct_out
15753 ok &= in_param_offset[12] == 144; ok &= in_param_size[12] == 72; // struct_inout
15754 ok &= in_param_offset[13] == 224; ok &= in_param_size[13] == 40; // uint32_t[10] array inout
15755 ok &= in_param_offset[14] == 264; ok &= in_param_size[14] == 8; // &size
15756 ok &= in_param_offset[15] == 280; ok &= in_param_size[15] == 16; // char[10] array in
15757 ok &= in_param_offset[16] == 296; ok &= in_param_size[16] == 8; // size
15758 ok &= in_param_offset[17] == 0; ok &= in_param_size[17] == 0; // char[16] array out
15759 ok &= in_param_offset[18] == 304; ok &= in_param_size[18] == 8; // &size
15760 ok &= in_offset == 312;
15761
15762 if (!ok) {
15763 cm_msg(MERROR, "rpc_execute_cxx", "RPC_TEST2 parameters encoding error!");
15764 return RPC_INVALID_ID;
15765 }
15766 }
15767
15768 if (debug) {
15769 printf("rpc_execute_cxx: calling dispatch()\n");
15770 }
15771
15772 /*********************************\
15773 * call dispatch function *
15774 \*********************************/
15775 if (rl.dispatch)
15776 status = rl.dispatch(routine_id, prpc_param);
15777 else
15779
15780 if (debug) {
15781 printf("rpc_execute_cxx: dispatch() status %d\n", status);
15782 }
15783
15784 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN || routine_id == RPC_ID_WATCHDOG)
15786
15787 /* return immediately for closed down client connections */
15788 if (!sock && routine_id == RPC_ID_EXIT) {
15789 return SS_EXIT;
15790 }
15791
15792 if (!sock && routine_id == RPC_ID_SHUTDOWN) {
15793 return RPC_SHUTDOWN;
15794 }
15795
15796 /* Return if TCP connection broken */
15797 if (status == SS_ABORT) {
15798 return SS_ABORT;
15799 }
15800
15801 /* if sock == 0, we are in FTCP mode and may not sent results */
15802 if (!sock) {
15803 return RPC_SUCCESS;
15804 }
15805
15806 std::vector<char> v_out;
15807
15808 v_out.resize(sizeof(NET_COMMAND_HEADER));
15809
15810 for (int i = 0; i < nparams; i++) {
15811 if (rl.param[i].flags & RPC_OUT) {
15812 int tid = rl.param[i].tid;
15813 int flags = rl.param[i].flags;
15814
15815 if (flags & RPC_CXX) {
15816 if (tid == TID_STRING) {
15817 size_t arg_size = 1 + params[i].ps->length();
15818 size_t param_size = ALIGN8(arg_size);
15819
15820 if (debug)
15821 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());
15822
15823 v_out.insert(v_out.end(), params[i].ps->c_str(), params[i].ps->c_str() + arg_size);
15824 v_out.resize(v_out.size() + param_size - arg_size); // pad to 8 bytes
15825 } else if (tid == TID_ARRAY) {
15826 size_t arg_size = params[i].pv->size();
15827 size_t param_size = ALIGN8(arg_size);
15828
15829 if (debug)
15830 printf("rpc_execute_cxx: param %2d, std::vector arg_size %zu, param_size %zu\n", i, arg_size, param_size);
15831
15832 char buf[ALIGN8(sizeof(INT))];
15833 *((INT *) buf) = arg_size; // store new array size
15834 if (convert_flags)
15835 rpc_convert_single(buf, TID_INT32, RPC_OUTGOING, convert_flags);
15836 v_out.insert(v_out.end(), buf, buf + ALIGN8(sizeof(INT))); // 8 bytes of param_size
15837 v_out.insert(v_out.end(), params[i].pv->data(), params[i].pv->data() + arg_size); // data
15838 v_out.resize(v_out.size() + param_size - arg_size); // pad data to 8 bytes
15839 } else {
15840 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);
15841 return RPC_INVALID_ID;
15842 }
15843 } else {
15844 size_t convert_offset = 0;
15845 size_t convert_size = 0;
15846
15847 if (tid == TID_STRING) {
15848 size_t max_size = params[i].out_max_size;
15849 char* param_ptr = (char *) prpc_param[i];
15850 //printf("param %d string param [%s] max_size %zu\n", i, param_ptr, max_size);
15851 size_t arg_size = 1 + strlen(param_ptr);
15852 if (arg_size > max_size) {
15853 param_ptr[max_size] = 0; // truncate!
15854 size_t arg_size = 1 + strlen(param_ptr);
15855 assert(arg_size == max_size);
15856 }
15857 size_t param_size = ALIGN8(arg_size);
15858
15859 if (debug)
15860 printf("rpc_execute_cxx: param %2d, string max_size %zu, string_size %zu, param_size %zu\n", i, max_size, arg_size, param_size);
15861
15862 v_out.insert(v_out.end(), param_ptr, param_ptr + arg_size);
15863 v_out.resize(v_out.size() + param_size - arg_size); // pad to 8 bytes
15864 } else if (flags & RPC_VARARRAY) {
15865 size_t max_size = params[i].out_max_size;
15866 size_t arg_size = *((INT *) prpc_param[i + 1]);
15867 char* param_ptr = (char*)prpc_param[i];
15868 size_t param_size = ALIGN8(arg_size);
15869
15870 if (debug)
15871 printf("rpc_execute_cxx: param %2d, array max_size %zu, param_size %zu\n", i, max_size, param_size);
15872
15873 char buf[ALIGN8(sizeof(INT))];
15874 *((INT *) buf) = arg_size; // store new array size
15875 if (convert_flags)
15876 rpc_convert_single(buf, TID_INT32, RPC_OUTGOING, convert_flags);
15877 v_out.insert(v_out.end(), buf, buf + ALIGN8(sizeof(INT))); // 8 bytes of param_size
15878 convert_offset = v_out.size();
15879 convert_size = arg_size;
15880 v_out.insert(v_out.end(), param_ptr, param_ptr + arg_size); // data
15881 v_out.resize(v_out.size() + param_size - arg_size); // pad data to 8 bytes
15882 } else {
15883 char* param_ptr = (char*)prpc_param[i];
15884 size_t arg_size = rpc_tid_size(tid);
15885 if (tid == TID_STRUCT)
15886 arg_size = rl.param[i].n;
15887 size_t param_size = ALIGN8(arg_size);
15888
15889 if (debug) {
15890 if (tid == TID_INT) {
15891 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);
15892 } else {
15893 printf("rpc_execute_cxx: param %2d, tid %2d, arg_size %zu, param_size %zu\n", i, tid, arg_size, param_size);
15894 }
15895 }
15896
15897 convert_offset = v_out.size();
15898 convert_size = arg_size;
15899 v_out.insert(v_out.end(), param_ptr, param_ptr + arg_size); // data
15900 v_out.resize(v_out.size() + param_size - arg_size); // pad data to 8 bytes
15901 }
15902
15903 /* convert data format */
15904 if (convert_flags) {
15905 if (flags & RPC_VARARRAY)
15906 rpc_convert_data(v_out.data()+convert_offset, tid, rl.param[i].flags | RPC_OUTGOING, convert_size, convert_flags);
15907 else
15908 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);
15909 }
15910 }
15911 }
15912 }
15913
15914 NET_COMMAND* nc_out = (NET_COMMAND*)v_out.data();
15915
15916 /* send return parameters */
15917 nc_out->header.routine_id = status;
15918 nc_out->header.param_size = v_out.size() - sizeof(NET_COMMAND_HEADER);
15919
15920
15921 /* convert header format (byte swapping) if necessary */
15922 if (convert_flags) {
15923 rpc_convert_single(&nc_out->header.routine_id, TID_UINT32, RPC_OUTGOING, convert_flags);
15924 rpc_convert_single(&nc_out->header.param_size, TID_UINT32, RPC_OUTGOING, convert_flags);
15925 }
15926
15927 status = send_tcp(sock, v_out.data(), v_out.size(), 0);
15928
15929 if (status < 0) {
15930 cm_msg(MERROR, "rpc_execute_cxx", "send_tcp() failed, status %d", status);
15931 return RPC_NET_ERROR;
15932 }
15933
15934 if (debug)
15935 printf("rpc_execute_cxx: send_tcp() sent %d bytes\n", status);
15936
15937 /* return SS_EXIT if RPC_EXIT is called */
15938 if (routine_id == RPC_ID_EXIT)
15939 return SS_EXIT;
15940
15941 /* return SS_SHUTDOWN if RPC_SHUTDOWN is called */
15942 if (routine_id == RPC_ID_SHUTDOWN)
15943 return RPC_SHUTDOWN;
15944
15945 return RPC_SUCCESS;
15946}
#define SS_EXIT
Definition midas.h:679
#define RPC_SHUTDOWN
Definition midas.h:708
#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:11846
#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:1585
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 15105 of file midas.cxx.

15132{
15133 INT i, routine_id, status;
15134 char *in_param_ptr, *out_param_ptr, *last_param_ptr;
15135 INT tid, flags;
15136 NET_COMMAND *nc_in, *nc_out;
15137 INT param_size, max_size;
15138 void *prpc_param[20];
15139 char debug_line[1024], *return_buffer;
15140 int return_buffer_size;
15141 int return_buffer_tls;
15142#ifdef FIXED_BUFFER
15143 int initial_buffer_size = NET_BUFFER_SIZE;
15144#else
15145 int initial_buffer_size = 1024;
15146#endif
15147
15148 /* return buffer must must use thread local storage multi-thread servers */
15149 if (!tls_size) {
15150 tls_buffer = (TLS_POINTER *) malloc(sizeof(TLS_POINTER));
15152 tls_buffer[tls_size].buffer_size = initial_buffer_size;
15153 tls_buffer[tls_size].buffer = (char *) malloc(tls_buffer[tls_size].buffer_size);
15154 tls_size = 1;
15155 }
15156 for (i = 0; i < tls_size; i++)
15157 if (tls_buffer[i].thread_id == ss_gettid())
15158 break;
15159 if (i == tls_size) {
15160 /* new thread -> allocate new buffer */
15161 tls_buffer = (TLS_POINTER *) realloc(tls_buffer, (tls_size + 1) * sizeof(TLS_POINTER));
15163 tls_buffer[tls_size].buffer_size = initial_buffer_size;
15164 tls_buffer[tls_size].buffer = (char *) malloc(tls_buffer[tls_size].buffer_size);
15165 tls_size++;
15166 }
15167
15168 return_buffer_tls = i;
15169 return_buffer_size = tls_buffer[i].buffer_size;
15170 return_buffer = tls_buffer[i].buffer;
15171 assert(return_buffer);
15172
15173 // make valgrind happy - the RPC parameter encoder skips the alignement padding bytes
15174 // and valgrind complains that we transmit uninitialized data
15175 //memset(return_buffer, 0, return_buffer_size);
15176
15177 /* extract pointer array to parameters */
15178 nc_in = (NET_COMMAND *) buffer;
15179
15180 /* convert header format (byte swapping) */
15181 if (convert_flags) {
15182 rpc_convert_single(&nc_in->header.routine_id, TID_UINT32, 0, convert_flags);
15183 rpc_convert_single(&nc_in->header.param_size, TID_UINT32, 0, convert_flags);
15184 }
15185
15186 //if (nc_in->header.routine_id & RPC_NO_REPLY) {
15187 // printf("rpc_execute: routine_id %d, RPC_NO_REPLY\n", (int)(nc_in->header.routine_id & ~RPC_NO_REPLY));
15188 //}
15189
15190 /* no result return as requested */
15191 if (nc_in->header.routine_id & RPC_NO_REPLY)
15192 sock = 0;
15193
15194 /* find entry in rpc_list */
15195 routine_id = nc_in->header.routine_id & ~RPC_NO_REPLY;
15196
15197 assert(xroutine_id == routine_id);
15198
15199 again:
15200
15201 in_param_ptr = nc_in->param;
15202
15203 nc_out = (NET_COMMAND *) return_buffer;
15204 out_param_ptr = nc_out->param;
15205
15206 sprintf(debug_line, "%s(", rl.name);
15207
15208 for (i = 0; rl.param[i].tid != 0; i++) {
15209 tid = rl.param[i].tid;
15210 flags = rl.param[i].flags;
15211
15212 if (flags & RPC_IN) {
15213 param_size = ALIGN8(rpc_tid_size(tid));
15214
15215 if (tid == TID_STRING || tid == TID_LINK)
15216 param_size = ALIGN8(1 + strlen((char *) (in_param_ptr)));
15217
15218 if (flags & RPC_VARARRAY) {
15219 /* for arrays, the size is stored as a INT in front of the array */
15220 param_size = *((INT *) in_param_ptr);
15221 if (convert_flags)
15222 rpc_convert_single(&param_size, TID_INT32, 0, convert_flags);
15223 param_size = ALIGN8(param_size);
15224
15225 in_param_ptr += ALIGN8(sizeof(INT));
15226 }
15227
15228 if (tid == TID_STRUCT)
15229 param_size = ALIGN8(rl.param[i].n);
15230
15231 prpc_param[i] = in_param_ptr;
15232
15233 /* convert data format */
15234 if (convert_flags) {
15235 if (flags & RPC_VARARRAY)
15236 rpc_convert_data(in_param_ptr, tid, flags, param_size, convert_flags);
15237 else
15238 rpc_convert_data(in_param_ptr, tid, flags, rl.param[i].n * rpc_tid_size(tid),
15239 convert_flags);
15240 }
15241
15242 std::string str = db_sprintf(in_param_ptr, param_size, 0, rl.param[i].tid);
15243 if (rl.param[i].tid == TID_STRING) {
15244 /* check for long strings (db_create_record...) */
15245 if (strlen(debug_line) + str.length() + 2 < sizeof(debug_line)) {
15246 strcat(debug_line, "\"");
15247 strcat(debug_line, str.c_str());
15248 strcat(debug_line, "\"");
15249 } else
15250 strcat(debug_line, "...");
15251 } else
15252 strcat(debug_line, str.c_str());
15253
15254 in_param_ptr += param_size;
15255 }
15256
15257 if (flags & RPC_OUT) {
15258 param_size = ALIGN8(rpc_tid_size(tid));
15259
15260 if (flags & RPC_VARARRAY || tid == TID_STRING) {
15261
15262 /* save maximum array length from the value of the next argument.
15263 * this means RPC_OUT arrays and strings should always be passed like this:
15264 * rpc_call(..., array_ptr, array_max_size, ...); */
15265
15266 max_size = *((INT *) in_param_ptr);
15267
15268 if (convert_flags)
15269 rpc_convert_single(&max_size, TID_INT32, 0, convert_flags);
15270 max_size = ALIGN8(max_size);
15271
15272 *((INT *) out_param_ptr) = max_size;
15273
15274 /* save space for return array length */
15275 out_param_ptr += ALIGN8(sizeof(INT));
15276
15277 /* use maximum array length from input */
15278 param_size = max_size;
15279 }
15280
15281 if (rl.param[i].tid == TID_STRUCT)
15282 param_size = ALIGN8(rl.param[i].n);
15283
15284 if ((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size > return_buffer_size) {
15285#ifdef FIXED_BUFFER
15286 cm_msg(MERROR, "rpc_execute",
15287 "return parameters (%d) too large for network buffer (%d)",
15288 (POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size, return_buffer_size);
15289
15290 return RPC_EXCEED_BUFFER;
15291#else
15292 int itls;
15293 int new_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size + 1024;
15294
15295#if 0
15296 cm_msg(MINFO, "rpc_execute",
15297 "rpc_execute: return parameters (%d) too large for network buffer (%d), new buffer size (%d)",
15298 (int)((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size), return_buffer_size, new_size);
15299#endif
15300
15301 itls = return_buffer_tls;
15302
15303 tls_buffer[itls].buffer_size = new_size;
15304 tls_buffer[itls].buffer = (char *) realloc(tls_buffer[itls].buffer, new_size);
15305
15306 if (!tls_buffer[itls].buffer) {
15307 cm_msg(MERROR, "rpc_execute", "Cannot allocate return buffer of size %d", new_size);
15308 return RPC_EXCEED_BUFFER;
15309 }
15310
15311 return_buffer_size = tls_buffer[itls].buffer_size;
15312 return_buffer = tls_buffer[itls].buffer;
15313 assert(return_buffer);
15314
15315 goto again;
15316#endif
15317 }
15318
15319 /* if parameter goes both directions, copy input to output */
15320 if (rl.param[i].flags & RPC_IN)
15321 memcpy(out_param_ptr, prpc_param[i], param_size);
15322
15323 if (_debug_print && !(flags & RPC_IN))
15324 strcat(debug_line, "-");
15325
15326 prpc_param[i] = out_param_ptr;
15327 out_param_ptr += param_size;
15328 }
15329
15330 if (rl.param[i + 1].tid)
15331 strcat(debug_line, ", ");
15332 }
15333
15334 //printf("predicted return size %d\n", (POINTER_T) out_param_ptr - (POINTER_T) nc_out);
15335
15336 strcat(debug_line, ")");
15337 rpc_debug_printf(debug_line);
15338
15339 last_param_ptr = out_param_ptr;
15340
15341 /*********************************\
15342 * call dispatch function *
15343 \*********************************/
15344 if (rl.dispatch)
15345 status = rl.dispatch(routine_id, prpc_param);
15346 else
15348
15349 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN || routine_id == RPC_ID_WATCHDOG)
15351
15352 /* return immediately for closed down client connections */
15353 if (!sock && routine_id == RPC_ID_EXIT)
15354 return SS_EXIT;
15355
15356 if (!sock && routine_id == RPC_ID_SHUTDOWN)
15357 return RPC_SHUTDOWN;
15358
15359 /* Return if TCP connection broken */
15360 if (status == SS_ABORT)
15361 return SS_ABORT;
15362
15363 /* if sock == 0, we are in FTCP mode and may not sent results */
15364 if (!sock)
15365 return RPC_SUCCESS;
15366
15367 /* compress variable length arrays */
15368 out_param_ptr = nc_out->param;
15369 for (i = 0; rl.param[i].tid != 0; i++)
15370 if (rl.param[i].flags & RPC_OUT) {
15371 tid = rl.param[i].tid;
15372 flags = rl.param[i].flags;
15373 param_size = ALIGN8(rpc_tid_size(tid));
15374
15375 if (tid == TID_STRING) {
15376 max_size = *((INT *) out_param_ptr);
15377 // note: RPC_OUT parameters may have been shifted in the output buffer by memmove()
15378 // and prpc_param() is now pointing to the wrong place. here we know our string data
15379 // starts right after max_size and we do not need to use prpc_param[] to find it. K.O.
15380 //const char* param_ptr = (char *) prpc_param[i];
15381 const char* param_ptr = ((char *) out_param_ptr) + ALIGN8(sizeof(INT));
15382 //printf("string param [%s] max_size %d\n", param_ptr, max_size);
15383 param_size = strlen(param_ptr) + 1;
15384 param_size = ALIGN8(param_size);
15385
15386 /* move string ALIGN8(sizeof(INT)) left */
15387 memmove(out_param_ptr, out_param_ptr + ALIGN8(sizeof(INT)), param_size);
15388
15389 /* move remaining parameters to end of string */
15390 memmove(out_param_ptr + param_size,
15391 out_param_ptr + max_size + ALIGN8(sizeof(INT)),
15392 (POINTER_T) last_param_ptr - ((POINTER_T) out_param_ptr + max_size + ALIGN8(sizeof(INT))));
15393 }
15394
15395 if (flags & RPC_VARARRAY) {
15396 /* store array length at current out_param_ptr */
15397 max_size = *((INT *) out_param_ptr);
15398 // note: RPC_OUT parameters may have been shifted in the output buffer by memmove()
15399 // and prpc_param() is now pointing to the wrong place. instead, compute location
15400 // of next parameter using max_size. K.O.
15401 // note: RPC_IN parameters are in the input buffer and we must use the prpc_param[] pointer. K.O.
15402 if (rl.param[i+1].flags & RPC_OUT)
15403 param_size = *((INT *) (out_param_ptr + ALIGN8(sizeof(INT)) + ALIGN8(max_size)));
15404 else
15405 param_size = *((INT *) prpc_param[i + 1]);
15406 *((INT *) out_param_ptr) = param_size; // store new array size
15407 if (convert_flags)
15408 rpc_convert_single(out_param_ptr, TID_INT32, RPC_OUTGOING, convert_flags);
15409
15410 out_param_ptr += ALIGN8(sizeof(INT)); // step over array size
15411
15412 param_size = ALIGN8(param_size);
15413
15414 /* move remaining parameters to end of array */
15415 memmove(out_param_ptr + param_size,
15416 out_param_ptr + max_size,
15417 (POINTER_T) last_param_ptr - ((POINTER_T) out_param_ptr + max_size));
15418 }
15419
15420 if (tid == TID_STRUCT)
15421 param_size = ALIGN8(rl.param[i].n);
15422
15423 /* convert data format */
15424 if (convert_flags) {
15425 if (flags & RPC_VARARRAY)
15426 rpc_convert_data(out_param_ptr, tid,
15427 rl.param[i].flags | RPC_OUTGOING, param_size, convert_flags);
15428 else
15429 rpc_convert_data(out_param_ptr, tid,
15430 rl.param[i].flags | RPC_OUTGOING,
15431 rl.param[i].n * rpc_tid_size(tid), convert_flags);
15432 }
15433
15434 out_param_ptr += param_size;
15435 }
15436
15437 /* send return parameters */
15438 param_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out->param;
15439 nc_out->header.routine_id = status;
15440 nc_out->header.param_size = param_size;
15441
15442 //printf("actual return size %d, buffer used %d\n", (POINTER_T) out_param_ptr - (POINTER_T) nc_out, sizeof(NET_COMMAND_HEADER) + param_size);
15443
15444 /* convert header format (byte swapping) if necessary */
15445 if (convert_flags) {
15446 rpc_convert_single(&nc_out->header.routine_id, TID_UINT32, RPC_OUTGOING, convert_flags);
15447 rpc_convert_single(&nc_out->header.param_size, TID_UINT32, RPC_OUTGOING, convert_flags);
15448 }
15449
15450 // valgrind complains about sending uninitialized data, if you care about this, uncomment
15451 // the memset(return_buffer,0) call above (search for "valgrind"). K.O.
15452
15453 status = send_tcp(sock, return_buffer, sizeof(NET_COMMAND_HEADER) + param_size, 0);
15454
15455 if (status < 0) {
15456 cm_msg(MERROR, "rpc_execute", "send_tcp() failed");
15457 return RPC_NET_ERROR;
15458 }
15459
15460 /* print return buffer */
15461/*
15462 printf("Return buffer, ID %d:\n", routine_id);
15463 for (i=0; i<param_size ; i++)
15464 {
15465 status = (char) nc_out->param[i];
15466 printf("%02X ", status);
15467 if (i%8 == 7)
15468 printf("\n");
15469 }
15470*/
15471 /* return SS_EXIT if RPC_EXIT is called */
15472 if (routine_id == RPC_ID_EXIT)
15473 return SS_EXIT;
15474
15475 /* return SS_SHUTDOWN if RPC_SHUTDOWN is called */
15476 if (routine_id == RPC_ID_SHUTDOWN)
15477 return RPC_SHUTDOWN;
15478
15479 return RPC_SUCCESS;
15480}
#define RPC_EXCEED_BUFFER
Definition midas.h:704
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:15102
void rpc_debug_printf(const char *format,...)
Definition midas.cxx:13301
static TLS_POINTER * tls_buffer
Definition midas.cxx:15101
midas_thread_t thread_id
Definition midas.cxx:15096
int buffer_size
Definition midas.cxx:15097
char * buffer
Definition midas.cxx:15098
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 13909 of file midas.cxx.

13910{
13911 rpc_list_mutex.lock();
13912
13913 for (size_t i = 0; i < rpc_list.size(); i++) {
13914 if (rpc_list[i].id == routine_id) {
13915 *pentry = rpc_list[i];
13916
13917 rpc_list_mutex.unlock();
13918
13919 *prpc_cxx = false;
13920
13921 for (int j=0; j<MAX_RPC_PARAMS; j++)
13922 if (pentry->param[j].flags & RPC_CXX)
13923 *prpc_cxx = true;
13924
13925 return RPC_SUCCESS;
13926 }
13927 }
13928
13929 rpc_list_mutex.unlock();
13930
13931 return RPC_INVALID_ID;
13932}
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 14495 of file midas.cxx.

14495 {
14496 return RPC_SUCCESS;
14497}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 17534 of file midas.cxx.

17548{
17549 bool has_data = ss_event_socket_has_data();
17550
17551 //printf("ss_event_socket_has_data() returned %d\n", has_data);
17552
17553 if (has_data) {
17554 if (timeout_msec == BM_NO_WAIT) {
17555 return BM_ASYNC_RETURN;
17556 } else if (timeout_msec == BM_WAIT) {
17557 return BM_ASYNC_RETURN;
17558 } else {
17559 int status = ss_suspend(timeout_msec, MSG_BM);
17560 if (status == SS_ABORT || status == SS_EXIT)
17561 return status;
17562 return BM_ASYNC_RETURN;
17563 }
17564 }
17565
17566 int status = rpc_server_receive_event(0, NULL, timeout_msec);
17567
17568 //printf("rpc_server_receive_event() status %d\n", status);
17569
17570 if (status == BM_ASYNC_RETURN) {
17571 return BM_ASYNC_RETURN;
17572 }
17573
17574 if (status == SS_ABORT || status == SS_EXIT)
17575 return status;
17576
17577 return BM_SUCCESS;
17578}
#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:17379
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 11746 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 13170 of file midas.cxx.

13181{
13184 else
13185 return 0;
13186}
Here is the caller graph for this function:

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12974 of file midas.cxx.

12985{
12986 {
12987 {
12988 INT tmp_type, size;
12989 DWORD dummy;
12990 unsigned char *p;
12991 float f;
12992 double d;
12993
12994 tmp_type = 0;
12995
12996 /* test pointer size */
12997 size = sizeof(p);
12998 if (size == 2)
12999 tmp_type |= DRI_16;
13000 if (size == 4)
13001 tmp_type |= DRI_32;
13002 if (size == 8)
13003 tmp_type |= DRI_64;
13004
13005 /* test if little or big endian machine */
13006 dummy = 0x12345678;
13007 p = (unsigned char *) &dummy;
13008 if (*p == 0x78)
13009 tmp_type |= DRI_LITTLE_ENDIAN;
13010 else if (*p == 0x12)
13011 tmp_type |= DRI_BIG_ENDIAN;
13012 else
13013 cm_msg(MERROR, "rpc_get_option", "unknown byte order format");
13014
13015 /* floating point format */
13016 f = (float) 1.2345;
13017 dummy = 0;
13018 memcpy(&dummy, &f, sizeof(f));
13019 if ((dummy & 0xFF) == 0x19 &&
13020 ((dummy >> 8) & 0xFF) == 0x04 && ((dummy >> 16) & 0xFF) == 0x9E
13021 && ((dummy >> 24) & 0xFF) == 0x3F)
13022 tmp_type |= DRF_IEEE;
13023 else if ((dummy & 0xFF) == 0x9E &&
13024 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x19
13025 && ((dummy >> 24) & 0xFF) == 0x04)
13026 tmp_type |= DRF_G_FLOAT;
13027 else
13028 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
13029
13030 d = (double) 1.2345;
13031 dummy = 0;
13032 memcpy(&dummy, &d, sizeof(f));
13033 if ((dummy & 0xFF) == 0x8D && /* little endian */
13034 ((dummy >> 8) & 0xFF) == 0x97 && ((dummy >> 16) & 0xFF) == 0x6E
13035 && ((dummy >> 24) & 0xFF) == 0x12)
13036 tmp_type |= DRF_IEEE;
13037 else if ((dummy & 0xFF) == 0x83 && /* big endian */
13038 ((dummy >> 8) & 0xFF) == 0xC0 && ((dummy >> 16) & 0xFF) == 0xF3
13039 && ((dummy >> 24) & 0xFF) == 0x3F)
13040 tmp_type |= DRF_IEEE;
13041 else if ((dummy & 0xFF) == 0x13 &&
13042 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x83
13043 && ((dummy >> 24) & 0xFF) == 0xC0)
13044 tmp_type |= DRF_G_FLOAT;
13045 else if ((dummy & 0xFF) == 0x9E &&
13046 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x18
13047 && ((dummy >> 24) & 0xFF) == 0x04)
13048 cm_msg(MERROR, "rpc_get_option",
13049 "MIDAS cannot handle VAX D FLOAT format. Please compile with the /g_float flag");
13050 else
13051 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
13052
13053 return tmp_type;
13054 }
13055 }
13056}
#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 12752 of file midas.cxx.

12753{
12755 if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12757 if (c && c->connected) {
12759 c->mutex.lock();
12760 if (!c->connected) {
12761 // disconnected while we were waiting for the lock
12762 c->mutex.unlock();
12763 return NULL;
12764 }
12765 return c;
12766 }
12767 }
12769 return NULL;
12770}
Here is the caller graph for this function:

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION * rpc_get_mserver_acception ( void  )

Definition at line 11653 of file midas.cxx.

11654{
11655 return _mserver_acception;
11656}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12945 of file midas.cxx.

12953{
12955}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13191 of file midas.cxx.

13199{
13200 return _mserver_path.c_str();
13201}
static std::string _mserver_path
Definition midas.cxx:13188
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13224 of file midas.cxx.

13242{
13243 return _client_name;
13244}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 14329 of file midas.cxx.

14329 {
14330 return _opt_tcp_size;
14331}
static int _opt_tcp_size
Definition midas.cxx:11716

◆ 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 13113 of file midas.cxx.

13114{
13115 if (hConn == RPC_HNDLE_MSERVER) {
13117 } else if (hConn == RPC_HNDLE_CONNECT) {
13118 return _rpc_connect_timeout;
13119 } else {
13121 if (c) {
13122 int timeout = c->rpc_timeout;
13123 c->mutex.unlock();
13124 return timeout;
13125 }
13126 }
13127 return 0;
13128}
#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 11801 of file midas.cxx.

11801 {
11802 unsigned short int i1, i2, i3, i4;
11803
11804 /* swap words */
11805 i1 = *((short int *) (var) + 3);
11806 i2 = *((short int *) (var) + 2);
11807 i3 = *((short int *) (var) + 1);
11808 i4 = *((short int *) (var));
11809
11810 /* correct exponent */
11811 if (i1 != 0)
11812 i1 += 0x20;
11813
11814 *((short int *) (var) + 3) = i4;
11815 *((short int *) (var) + 2) = i3;
11816 *((short int *) (var) + 1) = i2;
11817 *((short int *) (var)) = i1;
11818}
Here is the caller graph for this function:

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float *  var)

Definition at line 11751 of file midas.cxx.

11751 {
11752 unsigned short int lo, hi;
11753
11754 /* swap hi and lo word */
11755 lo = *((short int *) (var) + 1);
11756 hi = *((short int *) (var));
11757
11758 /* correct exponent */
11759 if (lo != 0)
11760 lo += 0x100;
11761
11762 *((short int *) (var) + 1) = hi;
11763 *((short int *) (var)) = lo;
11764}
Here is the caller graph for this function:

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 12923 of file midas.cxx.

12940{
12941 return _server_connection.send_sock != 0;
12942}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12958 of file midas.cxx.

12969{
12970 return _mserver_acception != NULL;
12971}
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12901 of file midas.cxx.

12918{
12919 return _rpc_is_remote;
12920}
static bool _rpc_is_remote
Definition midas.cxx:11647

◆ rpc_name_tid()

int rpc_name_tid ( const char *  name)

Definition at line 11918 of file midas.cxx.

11919{
11920 for (int i=0; i<TID_LAST; i++) {
11921 if (strcmp(name, tid_name[i]) == 0)
11922 return i;
11923 }
11924
11925 for (int i=0; i<TID_LAST; i++) {
11926 if (strcmp(name, tid_name_old[i]) == 0)
11927 return i;
11928 }
11929
11930 return 0;
11931}
#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 11658 of file midas.cxx.

11659{
11660 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11661 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11662 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11663 return _server_acceptions[idx];
11664 }
11665 }
11666
11668
11669 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11670 if (_server_acceptions[idx] == NULL) {
11671 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11672 _server_acceptions[idx] = sa;
11673 return _server_acceptions[idx];
11674 }
11675 }
11676
11677 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11678 _server_acceptions.push_back(sa);
11679
11680 return sa;
11681}
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 11948 of file midas.cxx.

11948 {
11952
11953 return RPC_SUCCESS;
11954}
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:11967
INT rpc_set_name(const char *name)
Definition midas.cxx:13248
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 12037 of file midas.cxx.

12056{
12057 std::lock_guard<std::mutex> guard(rpc_list_mutex);
12058
12059 for (size_t i = 0; i < rpc_list.size(); i++) {
12060 if (rpc_list[i].id == id) {
12061 rpc_list[i].dispatch = func;
12062 return RPC_SUCCESS;
12063 }
12064 }
12065
12066 return RPC_INVALID_ID;
12067}
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 11967 of file midas.cxx.

11968{
11969 for (int i = 0; new_list[i].id != 0; i++) {
11970 /* check valid ID for user functions */
11971 if (new_list != rpc_get_internal_list(0) &&
11972 new_list != rpc_get_internal_list(1) && (new_list[i].id < RPC_MIN_ID
11973 || new_list[i].id > RPC_MAX_ID)) {
11974 cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID %d", new_list[i].id);
11975 }
11976 }
11977
11978 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11979
11980 /* check double defined functions */
11981 for (int i = 0; new_list[i].id != 0; i++) {
11982 for (size_t j = 0; j < rpc_list.size(); j++) {
11983 if (rpc_list[j].id == new_list[i].id) {
11984 return RPC_DOUBLE_DEFINED;
11985 }
11986 }
11987 }
11988
11989 /* append new functions */
11990 for (int i = 0; new_list[i].id != 0; i++) {
11991 RPC_LIST e = new_list[i];
11992
11993 /* set default dispatcher */
11994 if (e.dispatch == NULL) {
11995 e.dispatch = func;
11996 }
11997
11998 rpc_list.push_back(e);
11999 }
12000
12001 return RPC_SUCCESS;
12002}
#define RPC_DOUBLE_DEFINED
Definition midas.h:710
#define RPC_MIN_ID
Definition midas.h:1590
#define RPC_MAX_ID
Definition midas.h:1591
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 15034 of file midas.cxx.

15057{
15058 /* register system functions: RPC_ID_EXIT, RPC_ID_SHUTDOWN, RPC_ID_WATCHDOG */
15060
15061 /* create a socket for listening */
15062 int lsock = 0;
15063 int lport = 0;
15064 std::string errmsg;
15065
15066 int status = ss_socket_listen_tcp(!disable_bind_rpc_to_localhost, port, &lsock, &lport, &errmsg);
15067
15068 if (status != SS_SUCCESS) {
15069 cm_msg(MERROR, "rpc_register_server", "cannot listen to tcp port %d: %s", port, errmsg.c_str());
15070 return RPC_NET_ERROR;
15071 }
15072
15073 /* set close-on-exec flag to prevent child mserver processes from inheriting the listen socket */
15074#if defined(F_SETFD) && defined(FD_CLOEXEC)
15075 status = fcntl(lsock, F_SETFD, fcntl(lsock, F_GETFD) | FD_CLOEXEC);
15076 if (status < 0) {
15077 cm_msg(MERROR, "rpc_register_server", "fcntl(F_SETFD, FD_CLOEXEC) failed, errno %d (%s)", errno, strerror(errno));
15078 return RPC_NET_ERROR;
15079 }
15080#endif
15081
15082 /* return port wich OS has choosen */
15083 if (pport) {
15084 *pport = lport;
15085 }
15086
15087 if (plsock)
15088 *plsock = lsock;
15089
15090 //printf("rpc_register_server: requested port %d, actual port %d, socket %d\n", port, *pport, *plsock);
15091
15092 return RPC_SUCCESS;
15093}
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 14993 of file midas.cxx.

15015{
15016 int status;
15017 int lsock;
15018
15019 status = rpc_register_listener(port, NULL, &lsock, pport);
15020 if (status != RPC_SUCCESS)
15021 return status;
15022
15024 if (status != SS_SUCCESS)
15025 return status;
15026
15027 if (plsock)
15028 *plsock = lsock;
15029
15030 return RPC_SUCCESS;
15031}
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:15034
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 14358 of file midas.cxx.

14359{
14360 if (rpc_is_remote()) {
14361 return rpc_send_event1(buffer_handle, pevent);
14362 } else {
14363 return bm_send_event(buffer_handle, pevent, unused, async_flag);
14364 }
14365}
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition midas.cxx:9698
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition midas.cxx:14376
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 14376 of file midas.cxx.

14377{
14378 const size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
14379 return rpc_send_event_sg(buffer_handle, 1, (char**)&pevent, &event_size);
14380}
INT rpc_send_event_sg(INT buffer_handle, int sg_n, const char *const sg_ptr[], const size_t sg_len[])
Definition midas.cxx:14382
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 14382 of file midas.cxx.

14383{
14384 if (sg_n < 1) {
14385 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_n %d", sg_n);
14386 return BM_INVALID_SIZE;
14387 }
14388
14389 if (sg_ptr[0] == NULL) {
14390 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_ptr[0] is NULL");
14391 return BM_INVALID_SIZE;
14392 }
14393
14394 if (sg_len[0] < sizeof(EVENT_HEADER)) {
14395 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));
14396 return BM_INVALID_SIZE;
14397 }
14398
14399 const EVENT_HEADER* pevent = (const EVENT_HEADER*)sg_ptr[0];
14400
14401 const DWORD MAX_DATA_SIZE = (0x7FFFFFF0 - 16); // event size computations are not 32-bit clean, limit event size to 2GB. K.O.
14402 const DWORD data_size = pevent->data_size; // 32-bit unsigned value
14403
14404 if (data_size == 0) {
14405 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size zero");
14406 return BM_INVALID_SIZE;
14407 }
14408
14409 if (data_size > MAX_DATA_SIZE) {
14410 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);
14411 return BM_INVALID_SIZE;
14412 }
14413
14414 const size_t event_size = sizeof(EVENT_HEADER) + data_size;
14415 const size_t total_size = ALIGN8(event_size);
14416
14417 size_t count = 0;
14418 for (int i=0; i<sg_n; i++) {
14419 count += sg_len[i];
14420 }
14421
14422 if (count != event_size) {
14423 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);
14424 return BM_INVALID_SIZE;
14425 }
14426
14427 // protect non-atomic access to _server_connection.event_sock. K.O.
14428
14429 std::lock_guard<std::mutex> guard(_server_connection.event_sock_mutex);
14430
14431 //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);
14432
14433 if (_server_connection.event_sock == 0) {
14434 return RPC_NO_CONNECTION;
14435 }
14436
14437 //
14438 // event socket wire protocol: (see also rpc_server_receive_event() and recv_event_server_realloc())
14439 //
14440 // 4 bytes of buffer handle
14441 // 16 bytes of event header, includes data_size
14442 // ALIGN8(data_size) bytes of event data
14443 //
14444
14445 int status;
14446
14447 /* send buffer handle */
14448
14449 assert(sizeof(DWORD) == 4);
14450 DWORD bh_buf = buffer_handle;
14451
14452 status = ss_write_tcp(_server_connection.event_sock, (const char *) &bh_buf, sizeof(DWORD));
14453 if (status != SS_SUCCESS) {
14455 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(buffer handle) failed, event socket is now closed");
14456 return RPC_NET_ERROR;
14457 }
14458
14459 /* send data */
14460
14461 for (int i=0; i<sg_n; i++) {
14462 status = ss_write_tcp(_server_connection.event_sock, sg_ptr[i], sg_len[i]);
14463 if (status != SS_SUCCESS) {
14465 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(event data) failed, event socket is now closed");
14466 return RPC_NET_ERROR;
14467 }
14468 }
14469
14470 /* send padding */
14471
14472 if (count < total_size) {
14473 char padding[8] = { 0,0,0,0,0,0,0,0 };
14474 size_t padlen = total_size - count;
14475 assert(padlen < 8);
14477 if (status != SS_SUCCESS) {
14479 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(padding) failed, event socket is now closed");
14480 return RPC_NET_ERROR;
14481 }
14482 }
14483
14484 return RPC_SUCCESS;
14485}
#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 16709 of file midas.cxx.

16730{
16731 INT i;
16732 INT sock;
16733 char version[NAME_LENGTH], v1[32];
16734 char experiment[NAME_LENGTH];
16735 INT port1, port2, port3;
16736 char *ptr;
16737 char net_buffer[256];
16738 struct linger ling;
16739
16740 static struct callback_addr callback;
16741
16742 if (lsock > 0) {
16743 sock = accept(lsock, NULL, NULL);
16744
16745 if (sock == -1)
16746 return RPC_NET_ERROR;
16747 } else {
16748 /* lsock is stdin -> already connected from inetd */
16749
16750 sock = lsock;
16751 }
16752
16753 /* check access control list */
16756
16757 if (status != RPC_SUCCESS) {
16758 ss_socket_close(&sock);
16759 return RPC_NET_ERROR;
16760 }
16761 }
16762
16763 /* receive string with timeout */
16764 i = recv_string(sock, net_buffer, 256, 10000);
16765 rpc_debug_printf("Received command: %s", net_buffer);
16766
16767 if (i > 0) {
16768 char command = (char) toupper(net_buffer[0]);
16769
16770 //printf("rpc_server_accept: command [%c]\n", command);
16771
16772 switch (command) {
16773 case 'S': {
16774
16775 /*----------- shutdown listener ----------------------*/
16776 ss_socket_close(&sock);
16777 return RPC_SHUTDOWN;
16778 }
16779 case 'I': {
16780
16781 /*----------- return available experiments -----------*/
16782#ifdef LOCAL_ROUTINES
16783 exptab_struct exptab;
16784 cm_read_exptab(&exptab); // thread safe!
16785 for (unsigned i=0; i<exptab.exptab.size(); i++) {
16786 rpc_debug_printf("Return experiment: %s", exptab.exptab[i].name.c_str());
16787 const char* str = exptab.exptab[i].name.c_str();
16788 send(sock, str, strlen(str) + 1, 0);
16789 }
16790 send(sock, "", 1, 0);
16791#endif
16792 ss_socket_close(&sock);
16793 break;
16794 }
16795 case 'C': {
16796
16797 /*----------- connect to experiment -----------*/
16798
16799 /* get callback information */
16800 callback.experiment[0] = 0;
16801 port1 = port2 = version[0] = 0;
16802
16803 //printf("rpc_server_accept: net buffer \'%s\'\n", net_buffer);
16804
16805 /* parse string in format "C port1 port2 port3 version expt" */
16806 /* example: C 51046 45838 56832 2.0.0 alpha */
16807
16808 port1 = strtoul(net_buffer + 2, &ptr, 0);
16809 port2 = strtoul(ptr, &ptr, 0);
16810 port3 = strtoul(ptr, &ptr, 0);
16811
16812 while (*ptr == ' ')
16813 ptr++;
16814
16815 i = 0;
16816 for (; *ptr != 0 && *ptr != ' ' && i < (int) sizeof(version) - 1;)
16817 version[i++] = *ptr++;
16818
16819 // ensure that we do not overwrite buffer "version"
16820 assert(i < (int) sizeof(version));
16821 version[i] = 0;
16822
16823 // skip wjatever is left from the "version" string
16824 for (; *ptr != 0 && *ptr != ' ';)
16825 ptr++;
16826
16827 while (*ptr == ' ')
16828 ptr++;
16829
16830 i = 0;
16831 for (; *ptr != 0 && *ptr != ' ' && *ptr != '\n' && *ptr != '\r' && i < (int) sizeof(experiment) - 1;)
16832 experiment[i++] = *ptr++;
16833
16834 // ensure that we do not overwrite buffer "experiment"
16835 assert(i < (int) sizeof(experiment));
16836 experiment[i] = 0;
16837
16839
16840 /* print warning if version patch level doesn't agree */
16841 mstrlcpy(v1, version, sizeof(v1));
16842 if (strchr(v1, '.'))
16843 if (strchr(strchr(v1, '.') + 1, '.'))
16844 *strchr(strchr(v1, '.') + 1, '.') = 0;
16845
16846 char str[100];
16847 mstrlcpy(str, cm_get_version(), sizeof(str));
16848 if (strchr(str, '.'))
16849 if (strchr(strchr(str, '.') + 1, '.'))
16850 *strchr(strchr(str, '.') + 1, '.') = 0;
16851
16852 if (strcmp(v1, str) != 0) {
16853 cm_msg(MERROR, "rpc_server_accept", "client MIDAS version %s differs from local version %s", version, cm_get_version());
16854 cm_msg(MERROR, "rpc_server_accept", "received string: %s", net_buffer + 2);
16855 }
16856
16857 callback.host_port1 = (short) port1;
16858 callback.host_port2 = (short) port2;
16859 callback.host_port3 = (short) port3;
16861
16863
16864 if (status != SS_SUCCESS) {
16865 ss_socket_close(&sock);
16866 break;
16867 }
16868
16869#ifdef LOCAL_ROUTINES
16870 /* update experiment definition */
16871 exptab_struct exptab;
16872 cm_read_exptab(&exptab); // thread safe!
16873
16874 unsigned idx = 0;
16875 bool found = false;
16876 /* lookup experiment */
16877 if (equal_ustring(callback.experiment.c_str(), "Default")) {
16878 found = true;
16879 idx = 0;
16880 } else {
16881 for (idx = 0; idx < exptab.exptab.size(); idx++) {
16882 if (exptab.exptab[idx].name == callback.experiment) {
16883 if (ss_dir_exist(exptab.exptab[idx].directory.c_str())) {
16884 found = true;
16885 break;
16886 }
16887 }
16888 }
16889 }
16890
16891 if (!found) {
16892 cm_msg(MERROR, "rpc_server_accept", "experiment \'%s\' not defined in exptab file \'%s\'", callback.experiment.c_str(), exptab.filename.c_str());
16893
16894 send(sock, "2", 2, 0); /* 2 means exp. not found */
16895 ss_socket_close(&sock);
16896 break;
16897 }
16898
16899 callback.directory = exptab.exptab[idx].directory;
16900 callback.user = exptab.exptab[idx].user;
16901
16902 /* create a new process */
16903 char host_port1_str[30], host_port2_str[30], host_port3_str[30];
16904 char debug_str[30];
16905
16906 sprintf(host_port1_str, "%d", callback.host_port1);
16907 sprintf(host_port2_str, "%d", callback.host_port2);
16908 sprintf(host_port3_str, "%d", callback.host_port3);
16909 sprintf(debug_str, "%d", callback.debug);
16910
16911 const char *mserver_path = rpc_get_mserver_path();
16912
16913 const char *argv[10];
16914 argv[0] = mserver_path;
16915 argv[1] = callback.host_name.c_str();
16916 argv[2] = host_port1_str;
16917 argv[3] = host_port2_str;
16918 argv[4] = host_port3_str;
16919 argv[5] = debug_str;
16920 argv[6] = callback.experiment.c_str();
16921 argv[7] = callback.directory.c_str();
16922 argv[8] = callback.user.c_str();
16923 argv[9] = NULL;
16924
16925 rpc_debug_printf("Spawn: %s %s %s %s %s %s %s %s %s %s",
16926 argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8],
16927 argv[9]);
16928
16929 status = ss_spawnv(P_NOWAIT, mserver_path, argv);
16930
16931 if (status != SS_SUCCESS) {
16932 rpc_debug_printf("Cannot spawn subprocess: %s\n", strerror(errno));
16933
16934 sprintf(str, "3"); /* 3 means cannot spawn subprocess */
16935 send(sock, str, strlen(str) + 1, 0);
16936 ss_socket_close(&sock);
16937 break;
16938 }
16939
16940 sprintf(str, "1 %s", cm_get_version()); /* 1 means ok */
16941 send(sock, str, strlen(str) + 1, 0);
16942#endif // LOCAL_ROUTINES
16943 ss_socket_close(&sock);
16944
16945 break;
16946 }
16947 default: {
16948 cm_msg(MERROR, "rpc_server_accept", "received unknown command '%c' code %d", command, command);
16949 ss_socket_close(&sock);
16950 break;
16951 }
16952 }
16953 } else { /* if i>0 */
16954
16955 /* lingering needed for PCTCP */
16956 ling.l_onoff = 1;
16957 ling.l_linger = 0;
16958 setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16959 ss_socket_close(&sock);
16960 }
16961
16962 return RPC_SUCCESS;
16963}
INT cm_read_exptab(exptab_struct *exptab)
Definition midas.cxx:1630
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:13191
#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:1617
std::vector< exptab_entry > exptab
Definition midas.cxx:1618
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 17070 of file midas.cxx.

17089{
17090 INT status;
17091 int recv_sock, send_sock, event_sock;
17092 char str[100];
17093 std::string client_program;
17094 INT client_hw_type, hw_type;
17095 INT convert_flags;
17096 char net_buffer[256];
17097 char *p;
17098 int flag;
17099
17100 /* copy callback information */
17101 struct callback_addr callback = *pcallback;
17102 //idx = callback.index;
17103
17104 std::string errmsg;
17105
17106 /* create new sockets for TCP */
17107 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port1, &recv_sock, &errmsg);
17108
17109 if (status != SS_SUCCESS) {
17110 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());
17111 ss_socket_close(&recv_sock);
17112 //ss_socket_close(&send_sock);
17113 //ss_socket_close(&event_sock);
17114 return RPC_NET_ERROR;
17115 }
17116
17117 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port2, &send_sock, &errmsg);
17118
17119 if (status != SS_SUCCESS) {
17120 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());
17121 ss_socket_close(&recv_sock);
17122 ss_socket_close(&send_sock);
17123 //ss_socket_close(&event_sock);
17124 return RPC_NET_ERROR;
17125 }
17126
17127 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port3, &event_sock, &errmsg);
17128
17129 if (status != SS_SUCCESS) {
17130 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());
17131 ss_socket_close(&recv_sock);
17132 ss_socket_close(&send_sock);
17133 ss_socket_close(&event_sock);
17134 return RPC_NET_ERROR;
17135 }
17136#ifndef OS_ULTRIX /* crashes ULTRIX... */
17137 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
17138 flag = 2 * 1024 * 1024;
17139 status = setsockopt(event_sock, SOL_SOCKET, SO_RCVBUF, (char *) &flag, sizeof(INT));
17140 if (status != 0)
17141 cm_msg(MERROR, "rpc_server_callback", "cannot setsockopt(SOL_SOCKET, SO_RCVBUF), errno %d (%s)", errno,
17142 strerror(errno));
17143#endif
17144
17145 if (recv_string(recv_sock, net_buffer, 256, _rpc_connect_timeout) <= 0) {
17146 cm_msg(MERROR, "rpc_server_callback", "timeout on receive remote computer info");
17147 ss_socket_close(&recv_sock);
17148 ss_socket_close(&send_sock);
17149 ss_socket_close(&event_sock);
17150 return RPC_NET_ERROR;
17151 }
17152 //printf("rpc_server_callback: \'%s\'\n", net_buffer);
17153
17154 /* get remote computer info */
17155 client_hw_type = strtoul(net_buffer, &p, 0);
17156
17157 while (*p == ' ')
17158 p++;
17159
17160 client_program = p;
17161
17162 //printf("hw type %d, name \'%s\'\n", client_hw_type, client_program);
17163
17164 std::string host_name;
17165
17166 status = ss_socket_get_peer_name(recv_sock, &host_name, NULL);
17167
17168 if (status != SS_SUCCESS)
17169 host_name = "unknown";
17170
17171 //printf("rpc_server_callback: mserver acception\n");
17172
17174
17175 /* save information in _server_acception structure */
17176 sa->recv_sock = recv_sock;
17177 sa->send_sock = send_sock;
17178 sa->event_sock = event_sock;
17179 sa->remote_hw_type = client_hw_type;
17180 sa->host_name = host_name;
17181 sa->prog_name = client_program;
17183 sa->watchdog_timeout = 0;
17184 sa->is_mserver = TRUE;
17185
17186 assert(_mserver_acception == NULL);
17187
17188 _mserver_acception = sa;
17189
17190 //printf("rpc_server_callback: _mserver_acception %p\n", _mserver_acception);
17191
17192 /* send my own computer id */
17193 hw_type = rpc_get_hw_type();
17194 sprintf(str, "%d", hw_type);
17195 send(recv_sock, str, strlen(str) + 1, 0);
17196
17197 rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
17198 sa->convert_flags = convert_flags;
17199
17201
17202 if (rpc_is_mserver()) {
17203 rpc_debug_printf("Connection to %s:%s established\n", sa->host_name.c_str(), sa->prog_name.c_str());
17204 }
17205
17206 return RPC_SUCCESS;
17207}
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 12521 of file midas.cxx.

12549{
12550 INT i, status;
12551 INT remote_hw_type, hw_type;
12552 char str[200], version[32], v1[32];
12553 fd_set readfds;
12554 struct timeval timeout;
12555 int port = MIDAS_TCP_PORT;
12556 char *s;
12557
12558#ifdef OS_WINNT
12559 {
12560 WSADATA WSAData;
12561
12562 /* Start windows sockets */
12563 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
12564 return RPC_NET_ERROR;
12565 }
12566#endif
12567
12568 /* check if local connection */
12569 if (host_name[0] == 0)
12570 return RPC_SUCCESS;
12571
12572 /* register system functions */
12574
12575 /* check if cm_connect_experiment was called */
12576 if (_client_name.length() == 0) {
12577 cm_msg(MERROR, "rpc_server_connect", "cm_connect_experiment/rpc_set_name not called");
12578 return RPC_NOT_REGISTERED;
12579 }
12580
12581 /* check if connection already exists */
12583 return RPC_SUCCESS;
12584
12588
12589 bool listen_localhost = false;
12590
12591 if (strcmp(host_name, "localhost") == 0)
12592 listen_localhost = true;
12593
12594 int lsock1, lport1;
12595 int lsock2, lport2;
12596 int lsock3, lport3;
12597
12598 std::string errmsg;
12599
12600 status = ss_socket_listen_tcp(listen_localhost, 0, &lsock1, &lport1, &errmsg);
12601
12602 if (status != SS_SUCCESS) {
12603 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12604 return RPC_NET_ERROR;
12605 }
12606
12607 status = ss_socket_listen_tcp(listen_localhost, 0, &lsock2, &lport2, &errmsg);
12608
12609 if (status != SS_SUCCESS) {
12610 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12611 return RPC_NET_ERROR;
12612 }
12613
12614 status = ss_socket_listen_tcp(listen_localhost, 0, &lsock3, &lport3, &errmsg);
12615
12616 if (status != SS_SUCCESS) {
12617 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12618 return RPC_NET_ERROR;
12619 }
12620
12621 /* extract port number from host_name */
12622 mstrlcpy(str, host_name, sizeof(str));
12623 s = strchr(str, ':');
12624 if (s) {
12625 *s = 0;
12626 port = strtoul(s + 1, NULL, 0);
12627 }
12628
12629 int sock;
12630
12631 status = ss_socket_connect_tcp(str, port, &sock, &errmsg);
12632
12633 if (status != SS_SUCCESS) {
12634 cm_msg(MERROR, "rpc_server_connect", "cannot connect to mserver on host \"%s\" port %d: %s", str, port, errmsg.c_str());
12635 return RPC_NET_ERROR;
12636 }
12637
12638 /* connect to experiment */
12639 if (exp_name[0] == 0)
12640 sprintf(str, "C %d %d %d %s Default", lport1, lport2, lport3, cm_get_version());
12641 else
12642 sprintf(str, "C %d %d %d %s %s", lport1, lport2, lport3, cm_get_version(), exp_name);
12643
12644 send(sock, str, strlen(str) + 1, 0);
12645 i = recv_string(sock, str, sizeof(str), _rpc_connect_timeout);
12646 ss_socket_close(&sock);
12647 if (i <= 0) {
12648 cm_msg(MERROR, "rpc_server_connect", "timeout on receive status from server");
12649 return RPC_NET_ERROR;
12650 }
12651
12652 status = version[0] = 0;
12653 sscanf(str, "%d %s", &status, version);
12654
12655 if (status == 2) {
12656/* message "undefined experiment" should be displayed by application */
12657 return CM_UNDEF_EXP;
12658 }
12659
12660 /* print warning if version patch level doesn't agree */
12661 strcpy(v1, version);
12662 if (strchr(v1, '.'))
12663 if (strchr(strchr(v1, '.') + 1, '.'))
12664 *strchr(strchr(v1, '.') + 1, '.') = 0;
12665
12666 strcpy(str, cm_get_version());
12667 if (strchr(str, '.'))
12668 if (strchr(strchr(str, '.') + 1, '.'))
12669 *strchr(strchr(str, '.') + 1, '.') = 0;
12670
12671 if (strcmp(v1, str) != 0) {
12672 cm_msg(MERROR, "rpc_server_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", version,
12673 cm_get_version());
12674 }
12675
12676 /* wait for callback on send and recv socket with timeout */
12677 FD_ZERO(&readfds);
12678 FD_SET(lsock1, &readfds);
12679 FD_SET(lsock2, &readfds);
12680 FD_SET(lsock3, &readfds);
12681
12682 timeout.tv_sec = _rpc_connect_timeout / 1000;
12683 timeout.tv_usec = 0;
12684
12685 do {
12686 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12687
12688 /* if an alarm signal was cought, restart select with reduced timeout */
12689 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
12690 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
12691
12692 } while (status == -1); /* dont return if an alarm signal was cought */
12693
12694 if (!FD_ISSET(lsock1, &readfds)) {
12695 cm_msg(MERROR, "rpc_server_connect", "mserver subprocess could not be started (check path)");
12696 ss_socket_close(&lsock1);
12697 ss_socket_close(&lsock2);
12698 ss_socket_close(&lsock3);
12699 return RPC_NET_ERROR;
12700 }
12701
12702 _server_connection.send_sock = accept(lsock1, NULL, NULL);
12703 _server_connection.recv_sock = accept(lsock2, NULL, NULL);
12704 _server_connection.event_sock = accept(lsock3, NULL, NULL);
12705
12707 cm_msg(MERROR, "rpc_server_connect", "accept() failed");
12708 return RPC_NET_ERROR;
12709 }
12710
12711 ss_socket_close(&lsock1);
12712 ss_socket_close(&lsock2);
12713 ss_socket_close(&lsock3);
12714
12715 /* set TCP_NODELAY option for better performance */
12716 int flag = 1;
12717 setsockopt(_server_connection.send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
12718 setsockopt(_server_connection.event_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
12719
12720 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
12721 flag = 2 * 1024 * 1024;
12722 status = setsockopt(_server_connection.event_sock, SOL_SOCKET, SO_SNDBUF, (char *) &flag, sizeof(flag));
12723 if (status != 0)
12724 cm_msg(MERROR, "rpc_server_connect", "cannot setsockopt(SOL_SOCKET, SO_SNDBUF), errno %d (%s)", errno, strerror(errno));
12725
12726 /* send local computer info */
12727 std::string local_prog_name = rpc_get_name();
12728 hw_type = rpc_get_hw_type();
12729 sprintf(str, "%d %s", hw_type, local_prog_name.c_str());
12730
12731 send(_server_connection.send_sock, str, strlen(str) + 1, 0);
12732
12733 /* receive remote computer info */
12735 if (i <= 0) {
12736 cm_msg(MERROR, "rpc_server_connect", "timeout on receive remote computer info");
12737 return RPC_NET_ERROR;
12738 }
12739
12740 sscanf(str, "%d", &remote_hw_type);
12741 _server_connection.remote_hw_type = remote_hw_type;
12742
12744
12745 _rpc_is_remote = true;
12746
12747 return RPC_SUCCESS;
12748}
#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 12845 of file midas.cxx.

12865{
12866 static int rpc_server_disconnect_recursion_level = 0;
12867
12868 if (rpc_server_disconnect_recursion_level)
12869 return RPC_SUCCESS;
12870
12871 rpc_server_disconnect_recursion_level = 1;
12872
12873 /* flush remaining events */
12875
12876 /* notify server about exit */
12877 if (rpc_is_connected()) {
12879 }
12880
12881 /* close sockets */
12888
12890
12891 /* remove semaphore */
12892 if (_mutex_rpc)
12894 _mutex_rpc = NULL;
12895
12896 rpc_server_disconnect_recursion_level = 0;
12897 return RPC_SUCCESS;
12898}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3290
bool rpc_is_connected(void)
Definition midas.cxx:12923
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:14124
INT rpc_flush_event()
Definition midas.cxx:14495
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 17211 of file midas.cxx.

17219{
17220 while (1) {
17221 int status = ss_suspend(1000, 0);
17222
17223 if (status == SS_ABORT || status == SS_EXIT)
17224 break;
17225
17227 break;
17228
17229 /* check alarms, etc */
17231
17233 }
17234
17235 return RPC_SUCCESS;
17236}
INT rpc_check_channels(void)
Definition midas.cxx:17652
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 17379 of file midas.cxx.

17393{
17394 int status = 0;
17395
17396 DWORD start_time = ss_millitime();
17397
17398 //
17399 // THIS IS NOT THREAD SAFE!!!
17400 //
17401 // IT IS ONLY USED BY THE MSERVER
17402 // MSERVER IS SINGLE-THREADED!!!
17403 //
17404
17405 static char *xbuf = NULL;
17406 static int xbufsize = 0;
17407 static bool xbufempty = true;
17408
17409 // short cut
17410 if (sa == NULL && xbufempty)
17411 return RPC_SUCCESS;
17412
17413 static bool recurse = false;
17414
17415 if (recurse) {
17416 cm_msg(MERROR, "rpc_server_receive_event", "internal error: called recursively");
17417 // do not do anything if we are called recursively
17418 // via recursive ss_suspend() or otherwise. K.O.
17419 if (xbufempty)
17420 return RPC_SUCCESS;
17421 else
17422 return BM_ASYNC_RETURN;
17423 }
17424
17425 recurse = true;
17426
17427 do {
17428 if (xbufempty && sa) {
17429 int n_received = recv_event_server_realloc(idx, sa, &xbuf, &xbufsize);
17430
17431 if (n_received < 0) {
17432 status = SS_ABORT;
17433 cm_msg(MERROR, "rpc_server_receive_event", "recv_event_server_realloc() returned %d, abort", n_received);
17434 goto error;
17435 }
17436
17437 if (n_received == 0) {
17438 // no more data in the tcp socket
17439 recurse = false;
17440 return RPC_SUCCESS;
17441 }
17442
17443 xbufempty = false;
17444 }
17445
17446 if (xbufempty) {
17447 // no event in xbuf buffer
17448 recurse = false;
17449 return RPC_SUCCESS;
17450 }
17451
17452 /* send event to buffer */
17453 INT *pbh = (INT *) xbuf;
17454 EVENT_HEADER *pevent = (EVENT_HEADER *) (pbh + 1);
17455
17456 status = bm_send_event(*pbh, pevent, 0, timeout_msec);
17457
17458 //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);
17459
17460 if (status == SS_ABORT) {
17461 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d (SS_ABORT), abort", status);
17462 goto error;
17463 }
17464
17465 if (status == BM_ASYNC_RETURN) {
17466 //cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, event buffer is full", status);
17467 recurse = false;
17468 return status;
17469 }
17470
17471 if (status != BM_SUCCESS) {
17472 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, mserver dropped this event", status);
17473 }
17474
17475 xbufempty = true;
17476
17477 /* repeat for maximum 0.5 sec */
17478 } while (ss_millitime() - start_time < 500);
17479
17480 recurse = false;
17481 return RPC_SUCCESS;
17482
17483 error:
17484
17485 {
17486 char str[80];
17487 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
17488 if (strchr(str, '.'))
17489 *strchr(str, '.') = 0;
17490 cm_msg(MTALK, "rpc_server_receive_event", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
17491 }
17492
17493 //exit:
17494
17496
17497 /* disconnect from experiment as MIDAS server */
17498 if (rpc_is_mserver()) {
17499 HNDLE hDB, hKey;
17500
17502
17503 /* only disconnect from experiment if previously connected.
17504 Necessary for pure RPC servers (RPC_SRVR) */
17505 if (hDB) {
17509
17511
17513 }
17514 }
17515
17516 bool is_mserver = sa->is_mserver;
17517
17518 sa->close();
17519
17520 /* signal caller a shutdonw */
17521 if (status == RPC_SHUTDOWN)
17522 return status;
17523
17524 /* only the mserver should stop on server connection closure */
17525 if (!is_mserver) {
17526 return SS_SUCCESS;
17527 }
17528
17529 return status;
17530}
INT bm_close_all_buffers(void)
Definition midas.cxx:7263
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3027
INT cm_delete_client_info(HNDLE hDB, INT pid)
Definition midas.cxx:1868
INT cm_set_experiment_database(HNDLE hDB, HNDLE hKeyClient)
Definition midas.cxx:2955
#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:14842
INT rpc_deregister_functions()
Definition midas.cxx:12010
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 17239 of file midas.cxx.

17254{
17255 int status = 0;
17256 int remaining = 0;
17257
17258 char *buf = NULL;
17259 int bufsize = 0;
17260
17261 do {
17262 int n_received = recv_net_command_realloc(sa, &buf, &bufsize, &remaining);
17263
17264 if (n_received <= 0) {
17265 status = SS_ABORT;
17266 cm_msg(MERROR, "rpc_server_receive_rpc", "recv_net_command() returned %d", n_received);
17267 goto error;
17268 }
17269
17270 /* extract pointer array to parameters */
17271 NET_COMMAND nc_in;
17272
17273 memcpy(&nc_in, buf, sizeof(nc_in));
17274
17275 /* convert header format (byte swapping) */
17276 if (sa->convert_flags) {
17279 }
17280
17281 int routine_id = nc_in.header.routine_id & ~RPC_NO_REPLY;
17282
17283 RPC_LIST rpc_entry;
17284 bool rpc_cxx = false;
17285
17286 status = rpc_find_rpc(routine_id, &rpc_entry, &rpc_cxx);
17287
17288 if (status != RPC_SUCCESS) {
17289 cm_msg(MERROR, "rpc_server_receive_rpc", "Unknown RPC routine_id %d", routine_id);
17290 goto error;
17291 }
17292
17293 if (rpc_cxx)
17294 status = rpc_execute_cxx(sa->recv_sock, routine_id, rpc_entry, buf, sa->convert_flags);
17295 else
17296 status = rpc_execute_old(sa->recv_sock, routine_id, rpc_entry, buf, sa->convert_flags);
17297
17298 if (status == SS_ABORT) {
17299 cm_msg(MERROR, "rpc_server_receive_rpc", "rpc_execute() returned %d, abort", status);
17300 goto error;
17301 }
17302
17303 if (status == SS_EXIT || status == RPC_SHUTDOWN) {
17304 if (rpc_is_mserver())
17305 rpc_debug_printf("Connection to %s:%s closed\n", sa->host_name.c_str(), sa->prog_name.c_str());
17306 goto exit;
17307 }
17308
17309 } while (remaining);
17310
17311 if (buf) {
17312 free(buf);
17313 buf = NULL;
17314 bufsize = 0;
17315 }
17316
17317 return RPC_SUCCESS;
17318
17319 error:
17320
17321 {
17322 char str[80];
17323 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
17324 if (strchr(str, '.'))
17325 *strchr(str, '.') = 0;
17326 cm_msg(MTALK, "rpc_server_receive_rpc", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
17327 }
17328
17329 exit:
17330
17332
17333 if (buf) {
17334 free(buf);
17335 buf = NULL;
17336 bufsize = 0;
17337 }
17338
17339 /* disconnect from experiment as MIDAS server */
17340 if (rpc_is_mserver()) {
17341
17342 if (status != SS_EXIT)
17343 cm_msg(MERROR, "rpc_server_receive_rpc", "mserver unexpected shutdown, status %d", status);
17344
17345 HNDLE hDB, hKey;
17346
17348
17349 /* only disconnect from experiment if previously connected.
17350 Necessary for pure RPC servers (RPC_SRVR) */
17351 if (hDB) {
17355
17357
17359 }
17360 }
17361
17362 bool is_mserver = sa->is_mserver;
17363
17364 sa->close();
17365
17366 /* signal caller a shutdonw */
17367 if (status == RPC_SHUTDOWN)
17368 return status;
17369
17370 /* only the mserver should stop on server connection closure */
17371 if (!is_mserver) {
17372 return SS_SUCCESS;
17373 }
17374
17375 return status;
17376}
static INT rpc_execute_old(INT sock, int xroutine_id, const RPC_LIST &rl, char *buffer, INT convert_flags)
Definition midas.cxx:15105
static INT rpc_execute_cxx(INT sock, int xroutine_id, const RPC_LIST &rl, char *buffer, INT convert_flags)
Definition midas.cxx:15512
static int recv_net_command_realloc(RPC_SERVER_ACCEPTION *sa, char **pbuf, int *pbufsize, INT *remaining)
Definition midas.cxx:14654
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 17581 of file midas.cxx.

17598{
17599 //printf("rpc_server_shutdown!\n");
17600
17601 struct linger ling;
17602
17603 /* close all open connections */
17604 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
17605 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
17607 /* lingering needed for PCTCP */
17608 ling.l_onoff = 1;
17609 ling.l_linger = 0;
17610 setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17612
17613 if (sa->send_sock) {
17614 setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17616 }
17617
17618 if (sa->event_sock) {
17619 setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
17621 }
17622 }
17623 }
17624
17625 /* avoid memory leak */
17626 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
17628 if (sa) {
17629 //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
17630 if (sa == _mserver_acception) {
17631 // do not leave behind a stale pointer!
17632 _mserver_acception = NULL;
17633 }
17634 delete sa;
17635 _server_acceptions[idx] = NULL;
17636 }
17637 }
17638
17639 if (_rpc_registered) {
17642 }
17643
17644 /* free suspend structures */
17646
17647 return RPC_SUCCESS;
17648}
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 13274 of file midas.cxx.

13294{
13295 _debug_print = func;
13296 _debug_mode = mode;
13297 return RPC_SUCCESS;
13298}
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char *  path)

Definition at line 13204 of file midas.cxx.

13218{
13219 _mserver_path = path;
13220 return RPC_SUCCESS;
13221}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char *  name)

Definition at line 13248 of file midas.cxx.

13266{
13268
13269 return RPC_SUCCESS;
13270}
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 14321 of file midas.cxx.

14321 {
14322 INT old;
14323
14324 old = _opt_tcp_size;
14325 _opt_tcp_size = tcp_size;
14326 return old;
14327}
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 13138 of file midas.cxx.

13139{
13140 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13141
13142 if (hConn == RPC_HNDLE_MSERVER) {
13143 if (old_timeout_msec)
13144 *old_timeout_msec = _server_connection.rpc_timeout;
13145 _server_connection.rpc_timeout = timeout_msec;
13146 } else if (hConn == RPC_HNDLE_CONNECT) {
13147 if (old_timeout_msec)
13148 *old_timeout_msec = _rpc_connect_timeout;
13149 _rpc_connect_timeout = timeout_msec;
13150 } else {
13152 if (c) {
13153 if (old_timeout_msec)
13154 *old_timeout_msec = c->rpc_timeout;
13155 c->rpc_timeout = timeout_msec;
13156 c->mutex.unlock();
13157 } else {
13158 if (old_timeout_msec)
13159 *old_timeout_msec = 0;
13160 }
13161 }
13162 return RPC_SUCCESS;
13163}
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 16681 of file midas.cxx.

16682{
16683 std::string hostname;
16684
16685 int status = ss_socket_get_peer_name(sock, &hostname, NULL);
16686
16687 if (status != SS_SUCCESS)
16688 return status;
16689
16690 status = rpc_check_allowed_host(hostname.c_str());
16691
16692 if (status == RPC_SUCCESS)
16693 return RPC_SUCCESS;
16694
16695 static std::atomic_int max_report(10);
16696 if (max_report > 0) {
16697 max_report--;
16698 if (max_report == 0) {
16699 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
16700 } else {
16701 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());
16702 }
16703 }
16704
16705 return RPC_NET_ERROR;
16706}
INT rpc_check_allowed_host(const char *hostname)
Definition midas.cxx:16632
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 16540 of file midas.cxx.

16556{
16557 int status;
16559 if (status != RPC_SUCCESS)
16560 return status;
16562 if (status != RPC_SUCCESS)
16563 return status;
16565 if (status != RPC_SUCCESS)
16566 return status;
16568 if (status != RPC_SUCCESS)
16569 return status;
16570 return RPC_SUCCESS;
16571}
int rpc_test_rpc_test2_cxx()
Definition midas.cxx:16111
int rpc_test_rpc_test2()
Definition midas.cxx:15949
int rpc_test_rpc_test3_cxx()
Definition midas.cxx:16271
int rpc_test_rpc_test4_cxx()
Definition midas.cxx:16427
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 15949 of file midas.cxx.

15965{
15966 int status = RPC_SUCCESS;
15967
15968 printf("rpc_test_rpc_test2!\n");
15969
15970 int int_out = 0;
15971 int int_inout = 456;
15972
15973 char string_out[33];
15974 char string2_out[49];
15975
15976 char string_inout[25];
15977 strcpy(string_inout, "string_inout");
15978
15979 KEY struct_in;
15980
15981 struct_in.type = 111;
15982 struct_in.num_values = 222;
15983 strcpy(struct_in.name, "name");
15984 struct_in.last_written = 333;
15985
15986 KEY struct_out;
15987 KEY struct_inout;
15988
15989 struct_inout.type = 111111;
15990 struct_inout.num_values = 222222;
15991 strcpy(struct_inout.name, "name_name");
15992 struct_inout.last_written = 333333;
15993
15994 uint32_t dwordarray_inout[9];
15995 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
15996
15997 for (int i=0; i<9; i++) {
15998 dwordarray_inout[i] = i*10;
15999 }
16000
16001 char array_in[10];
16002
16003 for (size_t i=0; i<sizeof(array_in); i++) {
16004 array_in[i] = 'a' + i;
16005 }
16006
16007 char array_out[16];
16008 size_t array_out_size = sizeof(array_out);
16009
16010 for (size_t i=0; i<sizeof(array_out); i++) {
16011 array_out[i] = 'Z';
16012 }
16013
16015 123,
16016 &int_out,
16017 &int_inout,
16018 "test string",
16019 string_out, sizeof(string_out),
16020 string2_out, sizeof(string2_out),
16021 string_inout, sizeof(string_inout),
16022 &struct_in,
16023 &struct_out,
16024 &struct_inout,
16025 dwordarray_inout, &dwordarray_inout_size,
16026 array_in, sizeof(array_in),
16027 array_out, &array_out_size
16028 );
16029
16030 if (status != RPC_SUCCESS) {
16031 printf("rpc_call(RPC_TEST2) status %d\n", status);
16032 return status;
16033 }
16034
16035 if (int_out != 789) {
16036 printf("int_out mismatch!\n");
16037 status = 0;
16038 }
16039
16040 if (int_inout != 456*2) {
16041 printf("int_inout mismatch!\n");
16042 status = 0;
16043 }
16044
16045 if (strcmp(string_out, "string_out") != 0) {
16046 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
16047 status = 0;
16048 }
16049
16050 if (strcmp(string2_out, "second string_out") != 0) {
16051 printf("string2_out mismatch [%s] vs [%s]\n", string2_out, "second string_out");
16052 status = 0;
16053 }
16054
16055 if (strcmp(string_inout, "return string_inout") != 0) {
16056 printf("string_inout mismatch [%s] vs [%s]\n", string_inout, "return string_inout");
16057 status = 0;
16058 }
16059
16060 KEY* pkey;
16061
16062 pkey = &struct_in;
16063
16064 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16065
16066 pkey = &struct_out;
16067
16068 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
16069 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);
16070 status = 0;
16071 }
16072
16073 pkey = &struct_inout;
16074
16075 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
16076 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);
16077 status = 0;
16078 }
16079
16080 if (dwordarray_inout_size != 4*5) {
16081 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
16082 status = 0;
16083 } else {
16084 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
16085 if (dwordarray_inout[i] != i*10+i) {
16086 printf("dwordarray_inout[%d] data mismatch %d vs %zu\n", (int)i, dwordarray_inout[i], i*10+i);
16087 status = 0;
16088 }
16089 }
16090 }
16091
16092 //printf("array_out_size %d\n", array_out_size);
16093 //for (int i=0; i<array_out_size; i++) {
16094 // printf("array_out[%d] is %3d (%c)\n", i, array_out[i], array_out[i]);
16095 //}
16096
16097 if (array_out_size != 15) {
16098 printf("array_out_size mismatch %d vs %d\n", (int)array_out_size, 15);
16099 status = 0;
16100 } else {
16101 if (strcmp(array_out, "test test test") != 0) {
16102 printf("array_out data mismatch\n");
16103 status = 0;
16104 }
16105 }
16106
16107 return status;
16108}
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 16111 of file midas.cxx.

16127{
16128 int status = RPC_SUCCESS;
16129
16130 printf("rpc_test_rpc_test2_cxx!\n");
16131
16132 int int_out = 0;
16133 int int_inout = 456;
16134
16135 char string_out[33];
16136 std::string string2_out;
16137 std::string string_inout = "string_inout";
16138
16139 KEY struct_in;
16140
16141 struct_in.type = 111;
16142 struct_in.num_values = 222;
16143 strcpy(struct_in.name, "name");
16144 struct_in.last_written = 333;
16145
16146 KEY struct_out;
16147 KEY struct_inout;
16148
16149 struct_inout.type = 111111;
16150 struct_inout.num_values = 222222;
16151 strcpy(struct_inout.name, "name_name");
16152 struct_inout.last_written = 333333;
16153
16154 uint32_t dwordarray_inout[9];
16155 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
16156
16157 for (int i=0; i<9; i++) {
16158 dwordarray_inout[i] = i*10;
16159 }
16160
16161 std::vector<char> array_in;
16162 int array_in_size = 10;
16163
16164 for (int i=0; i<array_in_size; i++) {
16165 array_in.push_back('a' + i);
16166 }
16167
16168 std::vector<char> array_out;
16169 size_t array_out_size = 16;
16170
16172 123,
16173 &int_out,
16174 &int_inout,
16175 "test string",
16176 string_out, sizeof(string_out),
16177 &string2_out, 48,
16178 &string_inout, 25,
16179 &struct_in,
16180 &struct_out,
16181 &struct_inout,
16182 dwordarray_inout, &dwordarray_inout_size,
16183 &array_in, array_in_size,
16184 &array_out, &array_out_size
16185 );
16186
16187 if (status != RPC_SUCCESS) {
16188 printf("rpc_call(RPC_TEST2_CXX) status %d\n", status);
16189 return status;
16190 }
16191
16192 if (int_out != 789) {
16193 printf("int_out mismatch!\n");
16194 status = 0;
16195 }
16196
16197 if (int_inout != 456*2) {
16198 printf("int_inout mismatch!\n");
16199 status = 0;
16200 }
16201
16202 if (strcmp(string_out, "string_out") != 0) {
16203 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
16204 status = 0;
16205 }
16206
16207 if (string2_out != "second string_out") {
16208 printf("string2_out mismatch [%s] vs [%s]\n", string2_out.c_str(), "second string_out");
16209 status = 0;
16210 }
16211
16212 if (string_inout != "return string_inout") {
16213 printf("string_inout mismatch [%s] vs [%s]\n", string_inout.c_str(), "return string_inout");
16214 status = 0;
16215 }
16216
16217 KEY* pkey;
16218
16219 pkey = &struct_in;
16220
16221 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16222
16223 pkey = &struct_out;
16224
16225 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
16226 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);
16227 status = 0;
16228 }
16229
16230 pkey = &struct_inout;
16231
16232 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
16233 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);
16234 status = 0;
16235 }
16236
16237 if (dwordarray_inout_size != 4*5) {
16238 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
16239 status = 0;
16240 } else {
16241 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
16242 if (dwordarray_inout[i] != i*10+i) {
16243 printf("dwordarray_inout[%d] data mismatch %d vs %zu\n", (int)i, dwordarray_inout[i], i*10+i);
16244 status = 0;
16245 }
16246 }
16247 }
16248
16249 //printf("array_out_size %d\n", array_out_size);
16250 //for (int i=0; i<array_out_size; i++) {
16251 // printf("array_out[%d] is %3d (%c)\n", i, array_out[i], array_out[i]);
16252 //}
16253
16254 if (array_out_size != 15) {
16255 printf("array_out_size mismatch %d vs %d\n", (int)array_out_size, 15);
16256 status = 0;
16257 } else if (array_out.size() != 15) {
16258 printf("array_out.size() mismatch %d vs %d\n", (int)array_out.size(), 15);
16259 status = 0;
16260 } else {
16261 if (strcmp(array_out.data(), "test test test") != 0) {
16262 printf("array_out data mismatch\n");
16263 status = 0;
16264 }
16265 }
16266
16267 return status;
16268}
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 16271 of file midas.cxx.

16287{
16288 int status = RPC_SUCCESS;
16289
16290 printf("rpc_test_rpc_test3_cxx!\n");
16291
16292 int int_out = 0;
16293 int int_inout = 456;
16294
16295 char string_out[33];
16296 std::string string2_out;
16297 std::string string_inout = "string_inout";
16298
16299 KEY struct_in;
16300
16301 struct_in.type = 111;
16302 struct_in.num_values = 222;
16303 strcpy(struct_in.name, "name");
16304 struct_in.last_written = 333;
16305
16306 KEY struct_out;
16307 KEY struct_inout;
16308
16309 struct_inout.type = 111111;
16310 struct_inout.num_values = 222222;
16311 strcpy(struct_inout.name, "name_name");
16312 struct_inout.last_written = 333333;
16313
16314 uint32_t dwordarray_inout[9];
16315 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
16316
16317 for (int i=0; i<9; i++) {
16318 dwordarray_inout[i] = i*10;
16319 }
16320
16321 std::vector<char> array_in;
16322 int array_in_size = 10;
16323
16324 for (int i=0; i<array_in_size; i++) {
16325 array_in.push_back('a' + i);
16326 }
16327
16328 std::vector<char> array_out;
16329
16331 123,
16332 &int_out,
16333 &int_inout,
16334 "test string",
16335 string_out, sizeof(string_out),
16336 &string2_out,
16337 &string_inout,
16338 &struct_in,
16339 &struct_out,
16340 &struct_inout,
16341 dwordarray_inout, &dwordarray_inout_size,
16342 &array_in,
16343 &array_out
16344 );
16345
16346 if (status != RPC_SUCCESS) {
16347 printf("rpc_call(RPC_TEST3_CXX) status %d\n", status);
16348 return status;
16349 }
16350
16351 if (int_out != 789) {
16352 printf("int_out mismatch!\n");
16353 status = 0;
16354 }
16355
16356 if (int_inout != 456*2) {
16357 printf("int_inout mismatch!\n");
16358 status = 0;
16359 }
16360
16361 if (strcmp(string_out, "string_out") != 0) {
16362 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
16363 status = 0;
16364 }
16365
16366 if (string2_out != "second string_out") {
16367 printf("string2_out mismatch [%s] vs [%s]\n", string2_out.c_str(), "second string_out");
16368 status = 0;
16369 }
16370
16371 if (string_inout != "return string_inout") {
16372 printf("string_inout mismatch [%s] vs [%s]\n", string_inout.c_str(), "return string_inout");
16373 status = 0;
16374 }
16375
16376 KEY* pkey;
16377
16378 pkey = &struct_in;
16379
16380 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
16381
16382 pkey = &struct_out;
16383
16384 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
16385 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);
16386 status = 0;
16387 }
16388
16389 pkey = &struct_inout;
16390
16391 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
16392 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);
16393 status = 0;
16394 }
16395
16396 if (dwordarray_inout_size != 4*5) {
16397 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
16398 status = 0;
16399 } else {
16400 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
16401 if (dwordarray_inout[i] != i*10+i) {
16402 printf("dwordarray_inout[%d] data mismatch %d vs %zu\n", (int)i, dwordarray_inout[i], i*10+i);
16403 status = 0;
16404 }
16405 }
16406 }
16407
16408 //printf("array_out_size %d\n", array_out_size);
16409 //for (int i=0; i<array_out_size; i++) {
16410 // printf("array_out[%d] is %3d (%c)\n", i, array_out[i], array_out[i]);
16411 //}
16412
16413 if (array_out.size() != 15) {
16414 printf("array_out.size() mismatch %d vs %d\n", (int)array_out.size(), 15);
16415 status = 0;
16416 } else {
16417 if (strcmp(array_out.data(), "test test test") != 0) {
16418 printf("array_out data mismatch\n");
16419 status = 0;
16420 }
16421 }
16422
16423 return status;
16424}
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 16427 of file midas.cxx.

16443{
16444 int status = RPC_SUCCESS;
16445
16446 printf("rpc_test_rpc_test4_cxx!\n");
16447
16448 int int_out = 0;
16449 int int_inout = 456;
16450
16451 std::string string_in = "test string";
16452 std::string string_out;
16453 std::string string_inout = "string_inout";
16454
16455 std::vector<char> array_in;
16456 int array_in_size = 10;
16457
16458 for (int i=0; i<array_in_size; i++) {
16459 array_in.push_back('a' + i);
16460 }
16461
16462 std::vector<char> array_out;
16463
16464 std::vector<char> array_inout;
16465 int array_inout_size = 6;
16466
16467 for (int i=0; i<array_inout_size; i++) {
16468 array_inout.push_back('0' + i);
16469 }
16470
16472 123,
16473 &int_out,
16474 &int_inout,
16475 &string_in,
16476 &string_out,
16477 &string_inout,
16478 &array_in,
16479 &array_out,
16480 &array_inout
16481 );
16482
16483 if (status != RPC_SUCCESS) {
16484 printf("rpc_call(RPC_TEST4_CXX) status %d\n", status);
16485 return status;
16486 }
16487
16488 if (int_out != 789) {
16489 printf("int_out mismatch!\n");
16490 status = 0;
16491 }
16492
16493 if (int_inout != 456*2) {
16494 printf("int_inout mismatch!\n");
16495 status = 0;
16496 }
16497
16498 if (string_out != "return string_out") {
16499 printf("string_out mismatch [%s] vs [%s]\n", string_out.c_str(), "return string_out");
16500 status = 0;
16501 }
16502
16503 if (string_inout != "return string_inout") {
16504 printf("string_inout mismatch [%s] vs [%s]\n", string_inout.c_str(), "return string_inout");
16505 status = 0;
16506 }
16507
16508 if (array_out.size() != 15) {
16509 printf("array_out.size() mismatch %d vs %d\n", (int)array_out.size(), 15);
16510 status = 0;
16511 } else {
16512 if (strcmp(array_out.data(), "test test test") != 0) {
16513 printf("array_out data mismatch\n");
16514 status = 0;
16515 }
16516 }
16517
16518 if (array_inout.size() != 12) {
16519 printf("array_inout.size() mismatch %d vs %d\n", (int)array_inout.size(), 12);
16520 status = 0;
16521 } else {
16522 for (int i=0; i<6; i++) {
16523 if (array_inout[i] != '0' + i) {
16524 printf("array_inout data mismatch, index %d, value %d should be %d\n", i, array_inout[i], ('0'+i));
16525 status = 0;
16526 }
16527 }
16528 for (int i=6; i<12; i++) {
16529 if (array_inout[i] != 2*('0' + (i-6))) {
16530 printf("array_inout data mismatch, index %d, value %d should be %d\n", i, array_inout[i], 2*('0'+i));
16531 status = 0;
16532 }
16533 }
16534 }
16535
16536 return status;
16537}
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 11904 of file midas.cxx.

11904 {
11905 if (id >= 0 && id < TID_LAST)
11906 return tid_name[id];
11907 else
11908 return "<unknown>";
11909}
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 11911 of file midas.cxx.

11911 {
11912 if (id >= 0 && id < TID_LAST)
11913 return tid_name_old[id];
11914 else
11915 return "<unknown>";
11916}
Here is the caller graph for this function:

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11897 of file midas.cxx.

11897 {
11898 if (id >= 0 && id < TID_LAST)
11899 return tid_size[id];
11900
11901 return 0;
11902}
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 14513 of file midas.cxx.

14532{
14533 /* erase error string */
14534 *(CSTRING(2)) = 0;
14535
14536 if (idx == RPC_RC_TRANSITION) {
14537 // find registered handler
14538 // NB: this code should match same code in cm_transition_call_direct()
14539 // NB: only use the first handler, this is how MIDAS always worked
14540 // NB: we could run all handlers, but we can return the status and error string of only one of them.
14541 _trans_table_mutex.lock();
14542 size_t n = _trans_table.size();
14543 _trans_table_mutex.unlock();
14544
14545 for (size_t i = 0; i < n; i++) {
14546 _trans_table_mutex.lock();
14548 _trans_table_mutex.unlock();
14549
14550 if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14551 if (tt.func) {
14552 /* execute callback if defined */
14553 return tt.func(CINT(1), CSTRING(2));
14554 } else {
14555 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14556 /* store transition in FIFO */
14559 _tr_fifo[_tr_fifo_wp].trans_time = time(NULL);
14561 _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14562 // implicit unlock
14563 return RPC_SUCCESS;
14564 }
14565 }
14566 }
14567 // no handler for this transition
14568 cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14569 return CM_SUCCESS;
14570 } else {
14571 cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14572 return RPC_INVALID_ID;
14573 }
14574}
#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:1606
#define CSTRING(_i)
Definition midas.h:1630
time_t trans_time
Definition midas.cxx:14504
int sequence_number
Definition midas.cxx:14505
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 13333 of file midas.cxx.

13333 {
13334 switch (arg_type) {
13335 /* On the stack, the minimum parameter size is sizeof(int).
13336 To avoid problems on little endian systems, treat all
13337 smaller parameters as int's */
13338 case TID_UINT8:
13339 case TID_INT8:
13340 case TID_CHAR:
13341 case TID_UINT16:
13342 case TID_INT16:
13343 *((int *) arg) = va_arg(*arg_ptr, int);
13344 break;
13345
13346 case TID_INT32:
13347 case TID_BOOL:
13348 *((INT *) arg) = va_arg(*arg_ptr, INT);
13349 break;
13350
13351 case TID_UINT32:
13352 *((DWORD *) arg) = va_arg(*arg_ptr, DWORD);
13353 break;
13354
13355 /* float variables are passed as double by the compiler */
13356 case TID_FLOAT:
13357 *((float *) arg) = (float) va_arg(*arg_ptr, double);
13358 break;
13359
13360 case TID_DOUBLE:
13361 *((double *) arg) = va_arg(*arg_ptr, double);
13362 break;
13363
13364 case TID_ARRAY:
13365 *((char **) arg) = va_arg(*arg_ptr, char *);
13366 break;
13367 }
13368}
Here is the caller graph for this function:

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double *  var)

Definition at line 11782 of file midas.cxx.

11782 {
11783 unsigned short int i1, i2, i3, i4;
11784
11785 /* swap words */
11786 i1 = *((short int *) (var) + 3);
11787 i2 = *((short int *) (var) + 2);
11788 i3 = *((short int *) (var) + 1);
11789 i4 = *((short int *) (var));
11790
11791 /* correct exponent */
11792 if (i4 != 0)
11793 i4 -= 0x20;
11794
11795 *((short int *) (var) + 3) = i4;
11796 *((short int *) (var) + 2) = i3;
11797 *((short int *) (var) + 1) = i2;
11798 *((short int *) (var)) = i1;
11799}
Here is the caller graph for this function:

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float *  var)

Definition at line 11766 of file midas.cxx.

11766 {
11767 unsigned short int lo, hi;
11768
11769 /* swap hi and lo word */
11770 lo = *((short int *) (var) + 1);
11771 hi = *((short int *) (var));
11772
11773 /* correct exponent */
11774 if (hi != 0)
11775 hi -= 0x100;
11776
11777 *((short int *) (var) + 1) = hi;
11778 *((short int *) (var)) = lo;
11779
11780}
Here is the caller graph for this function:

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11644 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11643 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11651 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13188 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11716 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11647 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11650 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11646 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14509 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14508 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14511 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14510 of file midas.cxx.

◆ gAllowedHosts

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

Definition at line 16574 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 16575 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11713 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11714 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 15101 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 15102 of file midas.cxx.