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

11675{
11676 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11677
11678 if (is_mserver) {
11679 assert(_mserver_acception == this);
11680 _mserver_acception = NULL;
11681 is_mserver = false;
11682 }
11683
11684 /* close server connection */
11685 if (recv_sock)
11687 if (send_sock)
11689 if (event_sock)
11691
11692 /* free TCP cache */
11693 if (net_buffer) {
11694 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11695 free(net_buffer);
11696 net_buffer = NULL;
11697 net_buffer_size = 0;
11698 }
11699
11700 /* mark this entry as invalid */
11701 clear();
11702}
INT ss_socket_close(int *sockp)
Definition system.cxx:5303
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11642
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 14568 of file midas.cxx.

14592{
14593 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14594
14595 if (_tr_fifo_wp == _tr_fifo_rp)
14596 return FALSE;
14597
14598 if (transition)
14600
14601 if (run_number)
14603
14604 if (trans_time)
14605 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14606
14607 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14608
14609 // implicit unlock
14610 return TRUE;
14611}
#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:14502
static int _tr_fifo_wp
Definition midas.cxx:14501
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14500
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14499
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14493
int run_number
Definition midas.cxx:14494
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 12062 of file midas.cxx.

12062 {
12063 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
12064 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
12065 /* update a changed record */
12066 HNDLE hDB = *((INT *) nc->param);
12067 HNDLE hKeyRoot = *((INT *) nc->param + 1);
12068 HNDLE hKey = *((INT *) nc->param + 2);
12069 int index = *((INT *) nc->param + 3);
12070 return db_update_record_local(hDB, hKeyRoot, hKey, index);
12071 }
12072 return CM_VERSION_MISMATCH;
12073}
#define CM_VERSION_MISMATCH
Definition midas.h:587
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition odb.cxx:13584
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 14833 of file midas.cxx.

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

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

14821{
14822 /* figure out to which connection socket belongs */
14823 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14824 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14825 return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14826 }
14827
14828 return 0;
14829}
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition midas.cxx:11641
Here is the caller graph for this function:

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char *  hostname)

Definition at line 16594 of file midas.cxx.

16611{
16612 //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
16613
16614 gAllowedHostsMutex.lock();
16615 gAllowedHosts.push_back(hostname);
16616 gAllowedHostsEnabled = true;
16617 gAllowedHostsMutex.unlock();
16618
16619 return RPC_SUCCESS;
16620}
#define RPC_SUCCESS
Definition midas.h:699
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition midas.cxx:16566
static std::vector< std::string > gAllowedHosts
Definition midas.cxx:16565
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 11714 of file midas.cxx.

11714 {
11715 *convert_flags = 0;
11716
11717 /* big/little endian conversion */
11718 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11719 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11720 && (hw_type & DRI_BIG_ENDIAN)))
11721 *convert_flags |= CF_ENDIAN;
11722
11723 /* float conversion between IEEE and VAX G */
11724 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11725 *convert_flags |= CF_VAX2IEEE;
11726
11727 /* float conversion between VAX G and IEEE */
11728 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11729 *convert_flags |= CF_IEEE2VAX;
11730
11732 //if (remote_hw_type & DR_ASCII)
11733 // *convert_flags |= CF_ASCII;
11734}
#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:1611
#define CF_IEEE2VAX
Definition midas.h:1612
#define CF_VAX2IEEE
Definition midas.h:1613
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 14115 of file midas.cxx.

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

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

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

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

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

16634{
16635 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
16636
16638 return RPC_SUCCESS;
16639
16640 if (strcmp(hostname, "localhost") == 0)
16641 return RPC_SUCCESS;
16642
16643 if (strcmp(hostname, "localhost.localdomain") == 0)
16644 return RPC_SUCCESS;
16645
16646 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
16647 return RPC_SUCCESS;
16648
16649 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
16650 return RPC_SUCCESS;
16651
16653
16654 gAllowedHostsMutex.lock();
16655
16656 for (const auto& h: gAllowedHosts) {
16657 if (h == hostname) {
16659 break;
16660 }
16661 }
16662
16663 gAllowedHostsMutex.unlock();
16664
16665 //if (status != RPC_SUCCESS)
16666 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
16667
16668 return status;
16669}
#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 17643 of file midas.cxx.

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

16585{
16586 gAllowedHostsMutex.lock();
16587 gAllowedHosts.clear();
16588 gAllowedHostsEnabled = false;
16589 gAllowedHostsMutex.unlock();
16590 return RPC_SUCCESS;
16591}
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 16957 of file midas.cxx.

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

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

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

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

12825{
12826 /* notify server about exit */
12827
12828 /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12829
12831
12832 return RPC_SUCCESS;
12833}
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13926
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 12076 of file midas.cxx.

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

11865{
11866 /* convert array */
11867 if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11868 int single_size = rpc_tid_size(tid);
11869 /* don't convert TID_ARRAY & TID_STRUCT */
11870 if (single_size == 0)
11871 return;
11872
11873 int n = total_size / single_size;
11874
11875 for (int i = 0; i < n; i++) {
11876 char* p = (char *) data + (i * single_size);
11877 rpc_convert_single(p, tid, flags, convert_flags);
11878 }
11879 } else {
11880 rpc_convert_single(data, tid, flags, convert_flags);
11881 }
11882}
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 11812 of file midas.cxx.

11812 {
11813
11814 if (convert_flags & CF_ENDIAN) {
11815 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11816 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11817 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11818 }
11819
11820 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11821 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11822 if (tid == TID_FLOAT)
11823 rpc_ieee2vax_float((float *) data);
11824 if (tid == TID_DOUBLE)
11825 rpc_ieee2vax_double((double *) data);
11826 }
11827
11828 if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11829 ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11830 if (tid == TID_FLOAT)
11831 rpc_vax2ieee_float((float *) data);
11832 if (tid == TID_DOUBLE)
11833 rpc_vax2ieee_double((double *) data);
11834 }
11835}
#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:11757
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11742
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11792
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11773
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 13292 of file midas.cxx.

13306{
13307 va_list argptr;
13308 char str[1000];
13309
13310 if (_debug_mode) {
13311 va_start(argptr, format);
13312 vsprintf(str, (char *) format, argptr);
13313 va_end(argptr);
13314
13315 if (_debug_print) {
13316 strcat(str, "\n");
13318 } else
13319 puts(str);
13320 }
13321}
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 12001 of file midas.cxx.

12018{
12019 rpc_list_mutex.lock();
12020 rpc_list.clear();
12021 rpc_list_mutex.unlock();
12022
12023 return RPC_SUCCESS;
12024}
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11704
static std::mutex rpc_list_mutex
Definition midas.cxx:11705
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 15503 of file midas.cxx.

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

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

13901{
13902 rpc_list_mutex.lock();
13903
13904 for (size_t i = 0; i < rpc_list.size(); i++) {
13905 if (rpc_list[i].id == routine_id) {
13906 *pentry = rpc_list[i];
13907
13908 rpc_list_mutex.unlock();
13909
13910 *prpc_cxx = false;
13911
13912 for (int j=0; j<MAX_RPC_PARAMS; j++)
13913 if (pentry->param[j].flags & RPC_CXX)
13914 *prpc_cxx = true;
13915
13916 return RPC_SUCCESS;
13917 }
13918 }
13919
13920 rpc_list_mutex.unlock();
13921
13922 return RPC_INVALID_ID;
13923}
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 14486 of file midas.cxx.

14486 {
14487 return RPC_SUCCESS;
14488}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 17525 of file midas.cxx.

17539{
17540 bool has_data = ss_event_socket_has_data();
17541
17542 //printf("ss_event_socket_has_data() returned %d\n", has_data);
17543
17544 if (has_data) {
17545 if (timeout_msec == BM_NO_WAIT) {
17546 return BM_ASYNC_RETURN;
17547 } else if (timeout_msec == BM_WAIT) {
17548 return BM_ASYNC_RETURN;
17549 } else {
17550 int status = ss_suspend(timeout_msec, MSG_BM);
17551 if (status == SS_ABORT || status == SS_EXIT)
17552 return status;
17553 return BM_ASYNC_RETURN;
17554 }
17555 }
17556
17557 int status = rpc_server_receive_event(0, NULL, timeout_msec);
17558
17559 //printf("rpc_server_receive_event() status %d\n", status);
17560
17561 if (status == BM_ASYNC_RETURN) {
17562 return BM_ASYNC_RETURN;
17563 }
17564
17565 if (status == SS_ABORT || status == SS_EXIT)
17566 return status;
17567
17568 return BM_SUCCESS;
17569}
#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:4615
bool ss_event_socket_has_data()
Definition system.cxx:4592
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:17370
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 11737 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 13161 of file midas.cxx.

13172{
13175 else
13176 return 0;
13177}
Here is the caller graph for this function:

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12965 of file midas.cxx.

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

12744{
12746 if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12748 if (c && c->connected) {
12750 c->mutex.lock();
12751 if (!c->connected) {
12752 // disconnected while we were waiting for the lock
12753 c->mutex.unlock();
12754 return NULL;
12755 }
12756 return c;
12757 }
12758 }
12760 return NULL;
12761}
Here is the caller graph for this function:

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION * rpc_get_mserver_acception ( void  )

Definition at line 11644 of file midas.cxx.

11645{
11646 return _mserver_acception;
11647}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12936 of file midas.cxx.

12944{
12946}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13182 of file midas.cxx.

13190{
13191 return _mserver_path.c_str();
13192}
static std::string _mserver_path
Definition midas.cxx:13179
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13215 of file midas.cxx.

13233{
13234 return _client_name;
13235}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 14320 of file midas.cxx.

14320 {
14321 return _opt_tcp_size;
14322}
static int _opt_tcp_size
Definition midas.cxx:11707

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

13105{
13106 if (hConn == RPC_HNDLE_MSERVER) {
13108 } else if (hConn == RPC_HNDLE_CONNECT) {
13109 return _rpc_connect_timeout;
13110 } else {
13112 if (c) {
13113 int timeout = c->rpc_timeout;
13114 c->mutex.unlock();
13115 return timeout;
13116 }
13117 }
13118 return 0;
13119}
#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 11792 of file midas.cxx.

11792 {
11793 unsigned short int i1, i2, i3, i4;
11794
11795 /* swap words */
11796 i1 = *((short int *) (var) + 3);
11797 i2 = *((short int *) (var) + 2);
11798 i3 = *((short int *) (var) + 1);
11799 i4 = *((short int *) (var));
11800
11801 /* correct exponent */
11802 if (i1 != 0)
11803 i1 += 0x20;
11804
11805 *((short int *) (var) + 3) = i4;
11806 *((short int *) (var) + 2) = i3;
11807 *((short int *) (var) + 1) = i2;
11808 *((short int *) (var)) = i1;
11809}
Here is the caller graph for this function:

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float *  var)

Definition at line 11742 of file midas.cxx.

11742 {
11743 unsigned short int lo, hi;
11744
11745 /* swap hi and lo word */
11746 lo = *((short int *) (var) + 1);
11747 hi = *((short int *) (var));
11748
11749 /* correct exponent */
11750 if (lo != 0)
11751 lo += 0x100;
11752
11753 *((short int *) (var) + 1) = hi;
11754 *((short int *) (var)) = lo;
11755}
Here is the caller graph for this function:

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 12914 of file midas.cxx.

12931{
12932 return _server_connection.send_sock != 0;
12933}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12949 of file midas.cxx.

12960{
12961 return _mserver_acception != NULL;
12962}
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12892 of file midas.cxx.

12909{
12910 return _rpc_is_remote;
12911}
static bool _rpc_is_remote
Definition midas.cxx:11638

◆ rpc_name_tid()

int rpc_name_tid ( const char *  name)

Definition at line 11909 of file midas.cxx.

11910{
11911 for (int i=0; i<TID_LAST; i++) {
11912 if (strcmp(name, tid_name[i]) == 0)
11913 return i;
11914 }
11915
11916 for (int i=0; i<TID_LAST; i++) {
11917 if (strcmp(name, tid_name_old[i]) == 0)
11918 return i;
11919 }
11920
11921 return 0;
11922}
#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 11649 of file midas.cxx.

11650{
11651 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11652 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11653 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11654 return _server_acceptions[idx];
11655 }
11656 }
11657
11659
11660 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11661 if (_server_acceptions[idx] == NULL) {
11662 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11663 _server_acceptions[idx] = sa;
11664 return _server_acceptions[idx];
11665 }
11666 }
11667
11668 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11669 _server_acceptions.push_back(sa);
11670
11671 return sa;
11672}
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 11939 of file midas.cxx.

11939 {
11943
11944 return RPC_SUCCESS;
11945}
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:11958
INT rpc_set_name(const char *name)
Definition midas.cxx:13239
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 12028 of file midas.cxx.

12047{
12048 std::lock_guard<std::mutex> guard(rpc_list_mutex);
12049
12050 for (size_t i = 0; i < rpc_list.size(); i++) {
12051 if (rpc_list[i].id == id) {
12052 rpc_list[i].dispatch = func;
12053 return RPC_SUCCESS;
12054 }
12055 }
12056
12057 return RPC_INVALID_ID;
12058}
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 11958 of file midas.cxx.

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

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

15006{
15007 int status;
15008 int lsock;
15009
15010 status = rpc_register_listener(port, NULL, &lsock, pport);
15011 if (status != RPC_SUCCESS)
15012 return status;
15013
15015 if (status != SS_SUCCESS)
15016 return status;
15017
15018 if (plsock)
15019 *plsock = lsock;
15020
15021 return RPC_SUCCESS;
15022}
INT ss_suspend_set_client_listener(int listen_socket)
Definition system.cxx:4356
INT rpc_register_listener(int port, RPC_HANDLER func, int *plsock, int *pport)
Definition midas.cxx:15025
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 14349 of file midas.cxx.

14350{
14351 if (rpc_is_remote()) {
14352 return rpc_send_event1(buffer_handle, pevent);
14353 } else {
14354 return bm_send_event(buffer_handle, pevent, unused, async_flag);
14355 }
14356}
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition midas.cxx:9689
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition midas.cxx:14367
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 14367 of file midas.cxx.

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

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

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

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

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

12856{
12857 static int rpc_server_disconnect_recursion_level = 0;
12858
12859 if (rpc_server_disconnect_recursion_level)
12860 return RPC_SUCCESS;
12861
12862 rpc_server_disconnect_recursion_level = 1;
12863
12864 /* flush remaining events */
12866
12867 /* notify server about exit */
12868 if (rpc_is_connected()) {
12870 }
12871
12872 /* close sockets */
12879
12881
12882 /* remove semaphore */
12883 if (_mutex_rpc)
12885 _mutex_rpc = NULL;
12886
12887 rpc_server_disconnect_recursion_level = 0;
12888 return RPC_SUCCESS;
12889}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3283
bool rpc_is_connected(void)
Definition midas.cxx:12914
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:14115
INT rpc_flush_event()
Definition midas.cxx:14486
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 17202 of file midas.cxx.

17210{
17211 while (1) {
17212 int status = ss_suspend(1000, 0);
17213
17214 if (status == SS_ABORT || status == SS_EXIT)
17215 break;
17216
17218 break;
17219
17220 /* check alarms, etc */
17222
17224 }
17225
17226 return RPC_SUCCESS;
17227}
INT rpc_check_channels(void)
Definition midas.cxx:17643
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 17370 of file midas.cxx.

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

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

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

13285{
13286 _debug_print = func;
13287 _debug_mode = mode;
13288 return RPC_SUCCESS;
13289}
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char *  path)

Definition at line 13195 of file midas.cxx.

13209{
13210 _mserver_path = path;
13211 return RPC_SUCCESS;
13212}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char *  name)

Definition at line 13239 of file midas.cxx.

13257{
13259
13260 return RPC_SUCCESS;
13261}
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 14312 of file midas.cxx.

14312 {
14313 INT old;
14314
14315 old = _opt_tcp_size;
14316 _opt_tcp_size = tcp_size;
14317 return old;
14318}
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 13129 of file midas.cxx.

13130{
13131 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13132
13133 if (hConn == RPC_HNDLE_MSERVER) {
13134 if (old_timeout_msec)
13135 *old_timeout_msec = _server_connection.rpc_timeout;
13136 _server_connection.rpc_timeout = timeout_msec;
13137 } else if (hConn == RPC_HNDLE_CONNECT) {
13138 if (old_timeout_msec)
13139 *old_timeout_msec = _rpc_connect_timeout;
13140 _rpc_connect_timeout = timeout_msec;
13141 } else {
13143 if (c) {
13144 if (old_timeout_msec)
13145 *old_timeout_msec = c->rpc_timeout;
13146 c->rpc_timeout = timeout_msec;
13147 c->mutex.unlock();
13148 } else {
13149 if (old_timeout_msec)
13150 *old_timeout_msec = 0;
13151 }
13152 }
13153 return RPC_SUCCESS;
13154}
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 16672 of file midas.cxx.

16673{
16674 std::string hostname;
16675
16676 int status = ss_socket_get_peer_name(sock, &hostname, NULL);
16677
16678 if (status != SS_SUCCESS)
16679 return status;
16680
16681 status = rpc_check_allowed_host(hostname.c_str());
16682
16683 if (status == RPC_SUCCESS)
16684 return RPC_SUCCESS;
16685
16686 static std::atomic_int max_report(10);
16687 if (max_report > 0) {
16688 max_report--;
16689 if (max_report == 0) {
16690 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
16691 } else {
16692 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());
16693 }
16694 }
16695
16696 return RPC_NET_ERROR;
16697}
INT rpc_check_allowed_host(const char *hostname)
Definition midas.cxx:16623
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 16531 of file midas.cxx.

16547{
16548 int status;
16550 if (status != RPC_SUCCESS)
16551 return status;
16553 if (status != RPC_SUCCESS)
16554 return status;
16556 if (status != RPC_SUCCESS)
16557 return status;
16559 if (status != RPC_SUCCESS)
16560 return status;
16561 return RPC_SUCCESS;
16562}
int rpc_test_rpc_test2_cxx()
Definition midas.cxx:16102
int rpc_test_rpc_test2()
Definition midas.cxx:15940
int rpc_test_rpc_test3_cxx()
Definition midas.cxx:16262
int rpc_test_rpc_test4_cxx()
Definition midas.cxx:16418
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 15940 of file midas.cxx.

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

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

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

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

11895 {
11896 if (id >= 0 && id < TID_LAST)
11897 return tid_name[id];
11898 else
11899 return "<unknown>";
11900}
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 11902 of file midas.cxx.

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

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11888 of file midas.cxx.

11888 {
11889 if (id >= 0 && id < TID_LAST)
11890 return tid_size[id];
11891
11892 return 0;
11893}
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 14504 of file midas.cxx.

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

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

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double *  var)

Definition at line 11773 of file midas.cxx.

11773 {
11774 unsigned short int i1, i2, i3, i4;
11775
11776 /* swap words */
11777 i1 = *((short int *) (var) + 3);
11778 i2 = *((short int *) (var) + 2);
11779 i3 = *((short int *) (var) + 1);
11780 i4 = *((short int *) (var));
11781
11782 /* correct exponent */
11783 if (i4 != 0)
11784 i4 -= 0x20;
11785
11786 *((short int *) (var) + 3) = i4;
11787 *((short int *) (var) + 2) = i3;
11788 *((short int *) (var) + 1) = i2;
11789 *((short int *) (var)) = i1;
11790}
Here is the caller graph for this function:

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float *  var)

Definition at line 11757 of file midas.cxx.

11757 {
11758 unsigned short int lo, hi;
11759
11760 /* swap hi and lo word */
11761 lo = *((short int *) (var) + 1);
11762 hi = *((short int *) (var));
11763
11764 /* correct exponent */
11765 if (hi != 0)
11766 hi -= 0x100;
11767
11768 *((short int *) (var) + 1) = hi;
11769 *((short int *) (var)) = lo;
11770
11771}
Here is the caller graph for this function:

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11635 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11634 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11642 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13179 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11707 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11638 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11641 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11637 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14500 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14499 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14502 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14501 of file midas.cxx.

◆ gAllowedHosts

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

Definition at line 16565 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 16566 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11704 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11705 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 15092 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 15093 of file midas.cxx.