/** * @brief Make a method call using a connected client * * This function is used to make a method call on @p client as defined in * @p content, using content-type defined by @p transport and the deserialization * function specified by @p cb. This should generally not be used by users, as azy_parser * will automatically generate the correct calls from a .azy file. * @param client The client (NOT NULL) * @param content The content containing the method name and parameters (NOT NULL) * @param transport The content-type (xml/json/etc) to use * @param cb The deserialization callback to use for the response * @return The #Azy_Client_Call_Id of the transmission, to be used with azy_client_callback_set, * or 0 on failure */ Azy_Client_Call_Id azy_client_call(Azy_Client *client, Azy_Content *content, Azy_Net_Transport transport, Azy_Content_Cb cb) { Eina_Strbuf *msg; Azy_Client_Handler_Data *hd; DBG("(client=%p, net=%p, content=%p)", client, client->net, content); if (!AZY_MAGIC_CHECK(client, AZY_MAGIC_CLIENT)) { AZY_MAGIC_FAIL(client, AZY_MAGIC_CLIENT); return 0; } EINA_SAFETY_ON_NULL_RETURN_VAL(client->net, 0); EINA_SAFETY_ON_NULL_RETURN_VAL(content, 0); EINA_SAFETY_ON_NULL_RETURN_VAL(content->method, 0); INFO("New method call: '%s'", content->method); while (++azy_client_send_id__ < 1) ; content->id = azy_client_send_id__; azy_net_transport_set(client->net, transport); if (!azy_content_serialize_request(content, transport)) return 0; azy_net_type_set(client->net, AZY_NET_TYPE_POST); if (!client->net->http.req.http_path) { WARN("URI currently set to NULL, defaulting to \"/\""); azy_net_uri_set(client->net, "/"); } azy_net_message_length_set(client->net, content->length); msg = azy_net_header_create(client->net); EINA_SAFETY_ON_NULL_GOTO(msg, error); if (azy_rpc_log_dom >= 0) { char buf[64]; snprintf(buf, sizeof(buf), "\nSENDING >>>>>>>>>>>>>>>>>>>>>>>>\n%%.%is%%.%llis\n>>>>>>>>>>>>>>>>>>>>>>>>", eina_strbuf_length_get(msg), content->length); RPC_DBG(buf, eina_strbuf_string_get(msg), content->buffer); } EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, eina_strbuf_string_get(msg), eina_strbuf_length_get(msg)), error); INFO("Send [1/2] complete! %zu bytes queued for sending.", eina_strbuf_length_get(msg)); eina_strbuf_free(msg); msg = NULL; EINA_SAFETY_ON_TRUE_GOTO(!ecore_con_server_send(client->net->conn, content->buffer, content->length), error); INFO("Send [2/2] complete! %lli bytes queued for sending.", content->length); ecore_con_server_flush(client->net->conn); hd = calloc(1, sizeof(Azy_Client_Handler_Data)); EINA_SAFETY_ON_NULL_RETURN_VAL(hd, 0); hd->client = client; hd->method = eina_stringshare_ref(content->method); hd->callback = cb; hd->type = AZY_NET_TYPE_POST; hd->content_data = content->data; hd->send = eina_strbuf_new(); eina_strbuf_append_length(hd->send, (char *)content->buffer, content->length); hd->id = azy_client_send_id__; AZY_MAGIC_SET(hd, AZY_MAGIC_CLIENT_DATA_HANDLER); if (!client->conns) { client->recv = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb)_azy_client_handler_data, hd); ecore_con_server_data_set(client->net->conn, client); } client->conns = eina_list_append(client->conns, hd); DBG("(client=%p, net=%p, content=%p, hd=%p)", client, client->net, content, hd); return azy_client_send_id__; error: if (msg) eina_strbuf_free(msg); return 0; }
void rpc__ncacn_init ( rpc_prot_call_epv_p_t *call_epv, rpc_prot_mgmt_epv_p_t *mgmt_epv, rpc_prot_binding_epv_p_t *binding_epv, rpc_prot_network_epv_p_t *network_epv, rpc_prot_fork_handler_fn_t *fork_handler, unsigned32 *st ) { CODING_ERROR (st); /* * Initialize the management counters. */ rpc__cn_mgmt_init (); /* * Initialize the CN lookaside list condition variable. */ RPC_COND_INIT (rpc_g_cn_lookaside_cond, rpc_g_global_mutex); /* * Initialize the global sequence number cell. */ rpc__cn_init_seqnum (); /* * Initialize the global call_id cell. */ rpc_g_cn_call_id = 0; /* * Initialize the call rep lookaside list. */ rpc__list_desc_init (&rpc_g_cn_call_lookaside_list, RPC_C_CN_CALL_LOOKASIDE_MAX, sizeof (rpc_cn_call_rep_t), RPC_C_MEM_CN_CALL_REP, (rpc_list_element_alloc_fn_t) rpc__cn_call_ccb_create, (rpc_list_element_alloc_fn_t) rpc__cn_call_ccb_free, &rpc_g_global_mutex, &rpc_g_cn_lookaside_cond); /* * Initialize binding_rep lookaside list. */ rpc__list_desc_init (&rpc_g_cn_binding_lookaside_list, RPC_C_CN_BINDING_LOOKASIDE_MAX, sizeof (rpc_cn_binding_rep_t), RPC_C_MEM_CN_BINDING_REP, NULL, NULL, &rpc_g_global_mutex, &rpc_g_cn_lookaside_cond); /* * Initialize fragment buffer lookaside lists. Note that 7 extra * bytes will be allocated per structure. This is so that we can * adjust the data pointer to be on an 8 byte boundary and still * have the same size data area. Note that the CN global mutex * cannot be used to protect the large fragbuf lookaside list, * hence the NULL input args for mutex and cond to * rpc__list_desc_init. This is because large fragbufs are given * to stubs which indirectly call the fragbuf free routine which * calls the list free routine. Since this fragbuf free routine is * also called internally, where the CN global mutex is held, * it would be difficult to determine whether the CN global mutex * needed to be acquired in the fragbuf free routine. */ rpc__list_desc_init (&rpc_g_cn_lg_fbuf_lookaside_list, RPC_C_CN_FRAGBUF_LOOKASIDE_MAX, RPC_C_CN_LG_FRAGBUF_ALLOC_SIZE + 7, RPC_C_MEM_CN_LG_FRAGBUF, NULL, NULL, NULL, NULL); rpc__list_desc_init (&rpc_g_cn_sm_fbuf_lookaside_list, RPC_C_CN_FRAGBUF_LOOKASIDE_MAX, RPC_C_CN_SM_FRAGBUF_ALLOC_SIZE + 7, RPC_C_MEM_CN_SM_FRAGBUF, NULL, NULL, &rpc_g_global_mutex, &rpc_g_cn_lookaside_cond); /* * Initialize the association control block lookaside list. */ rpc__list_desc_init (&rpc_g_cn_assoc_lookaside_list, RPC_C_CN_ASSOC_LOOKASIDE_MAX, sizeof(rpc_cn_assoc_t), RPC_C_MEM_CN_ASSOC, (rpc_list_element_alloc_fn_t) rpc__cn_assoc_acb_create, (rpc_list_element_alloc_fn_t) rpc__cn_assoc_acb_free, &rpc_g_global_mutex, &rpc_g_cn_lookaside_cond); /* * Initialize the association syntax element lookaside list. */ rpc__list_desc_init (&rpc_g_cn_syntax_lookaside_list, RPC_C_CN_SYNTAX_LOOKASIDE_MAX, sizeof(rpc_cn_syntax_t), RPC_C_MEM_CN_SYNTAX, NULL, NULL, &rpc_g_global_mutex, &rpc_g_cn_lookaside_cond); /* * Initialize the association security context element lookaside list. */ rpc__list_desc_init (&rpc_g_cn_sec_lookaside_list, RPC_C_CN_SEC_LOOKASIDE_MAX, sizeof(rpc_cn_sec_context_t), RPC_C_MEM_CN_SEC_CONTEXT, NULL, NULL, &rpc_g_global_mutex, &rpc_g_cn_lookaside_cond); /* * Initialize the association group table. */ rpc__cn_assoc_grp_tbl_init (); /* * Return the interface to the NCA Connection Protocol Service in the four * EPVs. */ *call_epv = &cn_call_epv; *mgmt_epv = &cn_mgmt_epv; *binding_epv = &cn_binding_epv; *network_epv = &cn_network_epv; if (RPC_DBG(rpc_es_dbg_stats, 5)) { atexit (rpc__cn_stats_print); } *fork_handler = NULL; *st = rpc_s_ok; }