/* 发送同步消息队列 */
_api int crtl_msgq_sync_send(crtl_mqd_t dst_mqd, const char *m_ptr, const size_t m_len,
void *ack, size_t *ack_len, int timeout_sec, long timeout_nanosec)
{
/* 入参有误 */
if(unlikely(!m_ptr) || unlikely(!m_len) || unlikely(!ack) || unlikely(!ack_len)) {
crtl_print_err("wrong params error.\n");
crtl_assert_fp(stderr, 0);
return CRTL_ERROR;
}
/* 为同步消息队列申请内存 */
struct __crtl_msgq_sync_msg_body _unused *__msgq_sync_msg = crtl_malloc1(1, sizeof(struct __crtl_msgq_sync_msg_body)+m_len);
if(unlikely(!__msgq_sync_msg)) {
/* 申请失败,退出 */
crtl_print_err("null pointer error.\n");
crtl_assert_fp(stderr, 0);
return CRTL_ERROR;
}
int _unused ret = CRTL_ERROR;
crtl_msgq_name_t __ack_snd_mq_name;
/* 消息队列名称 */
sprintf(__ack_snd_mq_name, "%s", __CRTL_MSGQ_NAME_GEN("TMP", "ACK"));
__crtl_dbg("MSGQ: %s\n", __ack_snd_mq_name);
/* 创建消息队列 - 非阻塞-需要提供超时机制 */
__msgq_sync_msg->__ack_snd_mqd = crtl_mq_open_nonblk(__ack_snd_mq_name,
__CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSG,
__CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSGSIZE);
if(__msgq_sync_msg->__ack_snd_mqd == CRTL_ERROR) {
/* 创建消息队列失败,释放内存,并退出 */
crtl_print_err("Create tmp msgq error.\n");
sleep(1);
crtl_mfree1(__msgq_sync_msg);
crtl_assert_fp(stderr, 0);
return CRTL_ERROR;
}
__crtl_dbg("OPEN: mqd %d, \n", __msgq_sync_msg->__ack_snd_mqd);
/* 创建临时消息队列成功,拷贝需要发送的数据 */
__msgq_sync_msg->msg_size = m_len;
memcpy(__msgq_sync_msg->msg_body, m_ptr, m_len);
__crtl_dbg("SEND: mqd %d, \n", dst_mqd);
/* 发送消息队列 */
int ready_to_send_len = sizeof(struct __crtl_msgq_sync_msg_body)+m_len;
int send_size = crtl_mq_send(dst_mqd, (char*)__msgq_sync_msg, ready_to_send_len, 10, 0,0,0);
if(send_size < ready_to_send_len) {
/* 如果失败,清空消息队列,删除文件,退出 */
crtl_print_err("send size not equal, need %d, but is %d, error(mqd %d).\n", ready_to_send_len, send_size, dst_mqd);
crtl_assert_fp(stderr, 0);
crtl_mq_close(__msgq_sync_msg->__ack_snd_mqd);
crtl_mq_unlink(__ack_snd_mq_name);
crtl_mfree1(__msgq_sync_msg);
return CRTL_ERROR;
}
__crtl_dbg("SEND: mqd %d, send_size %d , ready_to_send_len %d\n", dst_mqd, send_size, ready_to_send_len);
/* 从临时消息队列接收消息(等待消息接收端调用 crtl_msgq_sync_send_ack ) */
char __buf[__CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSGSIZE] = {0};
unsigned int m_prio;
int recv_ack_size = crtl_mq_receive(__msgq_sync_msg->__ack_snd_mqd,
__buf, __CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSGSIZE,
&m_prio, 1, timeout_sec, timeout_nanosec);
if(recv_ack_size <= 0) {
/* 如果接收失败或者超时,关闭临时消息队列,清空临时消息队列文件,释放内存 */
crtl_print_err("recv ack error: recv %d error.\n", recv_ack_size);
crtl_assert_fp(stderr, 0);
crtl_mq_close(__msgq_sync_msg->__ack_snd_mqd);
crtl_mq_unlink(__ack_snd_mq_name);
crtl_mfree1(__msgq_sync_msg);
return CRTL_ERROR;
}
__crtl_dbg("RECV ACK: mqd %d, ack_len %d\n", __msgq_sync_msg->__ack_snd_mqd, recv_ack_size);
/* 如果从临时消息队列接收消息成功,向ack赋值, */
*ack_len = recv_ack_size;
memcpy(ack, __buf, recv_ack_size);
__crtl_dbg("RECV ACK: mqd %d, ack_len %d\n", __msgq_sync_msg->__ack_snd_mqd, recv_ack_size);
/* 整体流程结束,释放资源 */
__crtl_dbg("MSGQ Close: %s\n", __ack_snd_mq_name);
crtl_mq_close(__msgq_sync_msg->__ack_snd_mqd);
crtl_mq_unlink(__ack_snd_mq_name);
crtl_mfree1(__msgq_sync_msg);
return send_size-sizeof(struct __crtl_msgq_sync_msg_body);
}
/* 发送同步消息队列ack */
_api int crtl_msgq_sync_send_ack(const void *const src_sync_msg, const void *ack_msg, size_t ack_len)
{
/* 入参有误 */
if(unlikely(!src_sync_msg) || unlikely(!ack_msg) || unlikely(!ack_len)) {
crtl_print_err("wrong params error.\n");
crtl_assert_fp(stderr, 0);
return CRTL_ERROR;
}
/* 解析同步消息中的msgq ID */
struct __crtl_msgq_sync_msg_body *sync_msgq_msg = (struct __crtl_msgq_sync_msg_body *)src_sync_msg;
crtl_mqd_t __tmp_mqd = sync_msgq_msg->__ack_snd_mqd;
/* 向临时消息队列发送ACK消息 */
int send_ack_size = crtl_mq_send(__tmp_mqd, (char*)ack_msg, ack_len, 0, 0,0,0);
if(send_ack_size < ack_len) {
crtl_print_err("send ack size not equal, need %d, but is %d, error.\n", ack_len, send_ack_size);
crtl_assert_fp(stderr, 0);
return CRTL_ERROR;
}
__crtl_dbg("MSGQ ACK SEND: mqd %d\n", __tmp_mqd);
return send_ack_size;
}