Functions | |
INT | rpc_register_client (const char *name, RPC_LIST *list) |
INT | rpc_register_functions (const RPC_LIST *new_list, INT(*func)(INT, void **)) |
INT | rpc_set_option (HNDLE hConn, INT item, INT value) |
INT | rpc_send_event (INT buffer_handle, void *source, INT buf_size, INT async_flag, INT mode) |
INT | rpc_flush_event () |
INT rpc_flush_event | ( | ) |
Send event residing in the TCP cache buffer filled by rpc_send_event. This routine should be called when a run is stopped.
Definition at line 10275 of file midas.c.
Referenced by scan_fragment(), send_event(), and tr_stop().
10276 { 10277 INT i; 10278 10279 if (!rpc_is_remote()) 10280 return RPC_SUCCESS; 10281 10282 /* return if rpc_send_event was not called */ 10283 if (!_tcp_buffer || _tcp_wp == 0) 10284 return RPC_SUCCESS; 10285 10286 /* empty TCP buffer */ 10287 if (_tcp_wp > 0) { 10288 i = send_tcp(_rpc_sock, _tcp_buffer + _tcp_rp, _tcp_wp - _tcp_rp, 0); 10289 10290 if (i != _tcp_wp - _tcp_rp) { 10291 cm_msg(MERROR, "rpc_flush_event", "send_tcp() failed"); 10292 return RPC_NET_ERROR; 10293 } 10294 } 10295 10296 _tcp_rp = _tcp_wp = 0; 10297 10298 return RPC_SUCCESS; 10299 }
INT rpc_register_client | ( | const char * | name, | |
RPC_LIST * | list | |||
) |
Register RPC client for standalone mode (without standard midas server)
list | Array of RPC_LIST structures containing function IDs and parameter definitions. The end of the list must be indicated by a function ID of zero. | |
name | Name of this client |
Definition at line 8083 of file midas.c.
08084 { 08085 rpc_set_name(name); 08086 rpc_register_functions(rpc_get_internal_list(0), NULL); 08087 rpc_register_functions(list, NULL); 08088 08089 return RPC_SUCCESS; 08090 }
Register a set of RPC functions (both as clients or servers)
new_list | Array of RPC_LIST structures containing function IDs and parameter definitions. The end of the list must be indicated by a function ID of zero. | |
func | Default dispatch function |
Definition at line 8103 of file midas.c.
Referenced by cm_connect_experiment1(), do_jrpc_rev0(), main(), and rpc_register_client().
08104 { 08105 INT i, j, iold, inew; 08106 08107 /* count number of new functions */ 08108 for (i = 0; new_list[i].id != 0; i++) { 08109 /* check double defined functions */ 08110 for (j = 0; rpc_list != NULL && rpc_list[j].id != 0; j++) 08111 if (rpc_list[j].id == new_list[i].id) 08112 return RPC_DOUBLE_DEFINED; 08113 } 08114 inew = i; 08115 08116 /* count number of existing functions */ 08117 for (i = 0; rpc_list != NULL && rpc_list[i].id != 0; i++); 08118 iold = i; 08119 08120 /* allocate new memory for rpc_list */ 08121 if (rpc_list == NULL) 08122 rpc_list = (RPC_LIST *) M_MALLOC(sizeof(RPC_LIST) * (inew + 1)); 08123 else 08124 rpc_list = (RPC_LIST *) realloc(rpc_list, sizeof(RPC_LIST) * (iold + inew + 1)); 08125 08126 if (rpc_list == NULL) { 08127 cm_msg(MERROR, "rpc_register_functions", "out of memory"); 08128 return RPC_NO_MEMORY; 08129 } 08130 08131 /* append new functions */ 08132 for (i = iold; i < iold + inew; i++) { 08133 memcpy(rpc_list + i, new_list + i - iold, sizeof(RPC_LIST)); 08134 08135 /* set default dispatcher */ 08136 if (rpc_list[i].dispatch == NULL) 08137 rpc_list[i].dispatch = func; 08138 08139 /* check valid ID for user functions */ 08140 if (new_list != rpc_get_internal_list(0) && 08141 new_list != rpc_get_internal_list(1) && (rpc_list[i].id < RPC_MIN_ID 08142 || rpc_list[i].id > RPC_MAX_ID)) 08143 cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID"); 08144 } 08145 08146 /* mark end of list */ 08147 rpc_list[i].id = 0; 08148 08149 return RPC_SUCCESS; 08150 }
Fast send_event routine which bypasses the RPC layer and sends the event directly at the TCP level.
buffer_handle | Handle of the buffer to send the event to. Must be obtained via bm_open_buffer. | |
source | Address of the event to send. It must have a proper event header. | |
buf_size | Size of event in bytes with header. | |
async_flag | SYNC / ASYNC flag. In ASYNC mode, the function returns immediately if it cannot send the event over the network. In SYNC mode, it waits until the packet is sent (blocking). | |
mode | Determines 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. |
Definition at line 10062 of file midas.c.
Referenced by receive_trigger_event(), and send_event().
10063 { 10064 INT i; 10065 NET_COMMAND *nc; 10066 unsigned long flag; 10067 BOOL would_block = 0; 10068 DWORD aligned_buf_size; 10069 10070 aligned_buf_size = ALIGN8(buf_size); 10071 _rpc_sock = mode == 0 ? _server_connection.send_sock : _server_connection.event_sock; 10072 10073 if ((INT) aligned_buf_size != (INT) (ALIGN8(((EVENT_HEADER *) source)->data_size + sizeof(EVENT_HEADER)))) { 10074 cm_msg(MERROR, "rpc_send_event", "event size mismatch"); 10075 return BM_INVALID_PARAM; 10076 } 10077 10078 if (!rpc_is_remote()) 10079 return bm_send_event(buffer_handle, source, buf_size, async_flag); 10080 10081 /* init network buffer */ 10082 if (!_tcp_buffer) 10083 _tcp_buffer = (char *) M_MALLOC(NET_TCP_SIZE); 10084 if (!_tcp_buffer) { 10085 cm_msg(MERROR, "rpc_send_event", "not enough memory to allocate network buffer"); 10086 return RPC_EXCEED_BUFFER; 10087 } 10088 10089 /* check if not enough space in TCP buffer */ 10090 if (aligned_buf_size + 4 * 8 + sizeof(NET_COMMAND_HEADER) >= (DWORD) (_opt_tcp_size - _tcp_wp) 10091 && _tcp_wp != _tcp_rp) { 10092 /* set socket to nonblocking IO */ 10093 if (async_flag == ASYNC) { 10094 flag = 1; 10095 #ifdef OS_VXWORKS 10096 ioctlsocket(_rpc_sock, FIONBIO, (int) &flag); 10097 #else 10098 ioctlsocket(_rpc_sock, FIONBIO, &flag); 10099 #endif 10100 } 10101 10102 i = send_tcp(_rpc_sock, _tcp_buffer + _tcp_rp, _tcp_wp - _tcp_rp, 0); 10103 10104 if (i < 0) 10105 #ifdef OS_WINNT 10106 would_block = (WSAGetLastError() == WSAEWOULDBLOCK); 10107 #else 10108 would_block = (errno == EWOULDBLOCK); 10109 #endif 10110 10111 /* set socket back to blocking IO */ 10112 if (async_flag == ASYNC) { 10113 flag = 0; 10114 #ifdef OS_VXWORKS 10115 ioctlsocket(_rpc_sock, FIONBIO, (int) &flag); 10116 #else 10117 ioctlsocket(_rpc_sock, FIONBIO, &flag); 10118 #endif 10119 } 10120 10121 /* increment read pointer */ 10122 if (i > 0) 10123 _tcp_rp += i; 10124 10125 /* check if whole buffer is sent */ 10126 if (_tcp_rp == _tcp_wp) 10127 _tcp_rp = _tcp_wp = 0; 10128 10129 if (i < 0 && !would_block) { 10130 cm_msg(MERROR, "rpc_send_event", "send_tcp() failed, return code = %d", i); 10131 return RPC_NET_ERROR; 10132 } 10133 10134 /* return if buffer is not emptied */ 10135 if (_tcp_wp > 0) 10136 return BM_ASYNC_RETURN; 10137 } 10138 10139 if (mode == 0) { 10140 nc = (NET_COMMAND *) (_tcp_buffer + _tcp_wp); 10141 nc->header.routine_id = RPC_BM_SEND_EVENT | TCP_FAST; 10142 nc->header.param_size = 4 * 8 + aligned_buf_size; 10143 10144 /* assemble parameters manually */ 10145 *((INT *) (&nc->param[0])) = buffer_handle; 10146 *((INT *) (&nc->param[8])) = buf_size; 10147 10148 /* send events larger than optimal buffer size directly */ 10149 if (aligned_buf_size + 4 * 8 + sizeof(NET_COMMAND_HEADER) >= (DWORD) _opt_tcp_size) { 10150 /* send header */ 10151 i = send_tcp(_rpc_sock, _tcp_buffer + _tcp_wp, sizeof(NET_COMMAND_HEADER) + 16, 0); 10152 if (i <= 0) { 10153 cm_msg(MERROR, "rpc_send_event", "send_tcp() failed, return code = %d", i); 10154 return RPC_NET_ERROR; 10155 } 10156 10157 /* send data */ 10158 i = send_tcp(_rpc_sock, (char *) source, aligned_buf_size, 0); 10159 if (i <= 0) { 10160 cm_msg(MERROR, "rpc_send_event", "send_tcp() failed, return code = %d", i); 10161 return RPC_NET_ERROR; 10162 } 10163 10164 /* send last two parameters */ 10165 *((INT *) (&nc->param[0])) = buf_size; 10166 *((INT *) (&nc->param[8])) = 0; 10167 i = send_tcp(_rpc_sock, &nc->param[0], 16, 0); 10168 if (i <= 0) { 10169 cm_msg(MERROR, "rpc_send_event", "send_tcp() failed, return code = %d", i); 10170 return RPC_NET_ERROR; 10171 } 10172 } else { 10173 /* copy event */ 10174 memcpy(&nc->param[16], source, buf_size); 10175 10176 /* last two parameters (buf_size and async_flag */ 10177 *((INT *) (&nc->param[16 + aligned_buf_size])) = buf_size; 10178 *((INT *) (&nc->param[24 + aligned_buf_size])) = 0; 10179 10180 _tcp_wp += nc->header.param_size + sizeof(NET_COMMAND_HEADER); 10181 } 10182 10183 } else { 10184 10185 /* send events larger than optimal buffer size directly */ 10186 if (aligned_buf_size + 4 * 8 + sizeof(INT) >= (DWORD) _opt_tcp_size) { 10187 /* send buffer */ 10188 i = send_tcp(_rpc_sock, (char *) &buffer_handle, sizeof(INT), 0); 10189 if (i <= 0) { 10190 cm_msg(MERROR, "rpc_send_event", "send_tcp() failed, return code = %d", i); 10191 return RPC_NET_ERROR; 10192 } 10193 10194 /* send data */ 10195 i = send_tcp(_rpc_sock, (char *) source, aligned_buf_size, 0); 10196 if (i <= 0) { 10197 cm_msg(MERROR, "rpc_send_event", "send_tcp() failed, return code = %d", i); 10198 return RPC_NET_ERROR; 10199 } 10200 } else { 10201 /* copy event */ 10202 *((INT *) (_tcp_buffer + _tcp_wp)) = buffer_handle; 10203 _tcp_wp += sizeof(INT); 10204 memcpy(_tcp_buffer + _tcp_wp, source, buf_size); 10205 10206 _tcp_wp += aligned_buf_size; 10207 } 10208 } 10209 10210 return RPC_SUCCESS; 10211 }
Set RPC option
hConn | RPC connection handle, -1 for server connection, -2 for rpc connect timeout | |
item | One of RPC_Oxxx | |
value | Value to set |
Definition at line 9135 of file midas.c.
Referenced by bm_receive_event(), cm_transition1(), command_loop(), db_send_changed_records(), main(), and update_odb().
09136 { 09137 switch (item) { 09138 case RPC_OTIMEOUT: 09139 if (hConn == -1) 09140 _server_connection.rpc_timeout = value; 09141 else if (hConn == -2) 09142 _rpc_connect_timeout = value; 09143 else 09144 _client_connection[hConn - 1].rpc_timeout = value; 09145 break; 09146 09147 case RPC_OTRANSPORT: 09148 if (hConn == -1) 09149 _server_connection.transport = value; 09150 else 09151 _client_connection[hConn - 1].transport = value; 09152 break; 09153 09154 case RPC_NODELAY: 09155 if (hConn == -1) 09156 setsockopt(_server_connection.send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &value, sizeof(value)); 09157 else 09158 setsockopt(_client_connection[hConn - 1].send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &value, 09159 sizeof(value)); 09160 break; 09161 09162 default: 09163 cm_msg(MERROR, "rpc_set_option", "invalid argument"); 09164 break; 09165 } 09166 09167 return 0; 09168 }