apt_poller_tas.apt_poller_task_run–> mrcp_client_connection.mrcp_client_poller_signal_process–>
sendrecv.apr_socket_recv –>
mrcp_stream.mrcp_parser_run –>
mrcp_client_connection.mrcp_client_message_handler–>
mrcp_client_connection.mrcp_connection_channel_find–>
mrcp_connection_types.mrcp_connection_message_receive–>
mrcp_client.mrcp_client_message_signal–>
mrcp_client.mrcp_client_connection_task_msg_signal–>
apt_task.apt_task_msg_signal–>
apt_consumer_task.apt_consumer_task_msg_signal–>
apr_queue.apr_queue_push
pt_poller_task_run是一个无线循环,会不断调用mrcp_client_poller_signal_process()函数,在mrcp_client_poller_signal_process()中,会通过apr_socket_recv函数在socket上阻塞等待数据,然后通过mrcp_parser_run解析接收到的数据包。
这个函数的实现我在博文freeswitch mrcp 源码分析–数据解析已经进行了详细介绍。
数据解析完成后会调用mrcp_client_message_handler处理接收到的数据,
在mrcp_client_message_handler中先调用mrcp_connection_channel_find通过通道编码找到对应的通道,然后调用mrcp_connection_message_receiv处理接收到的数据。
mrcp_connection_message_receive的代码如下。可以看到主要是调用了vtable->on_receive。
static APR_INLINE apt_bool_t mrcp_connection_message_receive(
const mrcp_connection_event_vtable_t *vtable,
mrcp_control_channel_t *channel,
mrcp_message_t *message)
{
if(vtable && vtable->on_receive) {
return vtable->on_receive(channel,message);
}
return FALSE;
}
vtable是一个mrcp_connection_event_vtable_t对象:
static const mrcp_connection_event_vtable_t connection_method_vtable = {
mrcp_client_channel_add_signal,
mrcp_client_channel_modify_signal,
mrcp_client_channel_remove_signal,
mrcp_client_message_signal,
mrcp_client_disconnect_signal
};
所以会执行mrcp_client_message_signal函数,进而调用mrcp_client_connection_task_msg_signal,简单组装参数后会调用apt_task_msg_signal,
APT_DECLARE(apt_bool_t) apt_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg)
{
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Message to [%s] ["APT_PTR_FMT";%d;%d]",
task->name, msg, msg->type, msg->sub_type);
if(task->vtable.signal_msg) {
if(task->vtable.signal_msg(task,msg) == TRUE) {
return TRUE;
}
}
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Task Message [%s] [0x%x;%d;%d]",
task->name, msg, msg->type, msg->sub_type);
apt_task_msg_release(msg);
return FALSE;
}
所以主要调用了task->vtable.signal_msg函数,这里task是一个apt_task_t结构图,在创建的时候signal_msg被赋值为apt_consumer_task_msg_signal:
APT_DECLARE(apt_consumer_task_t*) apt_consumer_task_create(
void *obj,
apt_task_msg_pool_t *msg_pool,
apr_pool_t *pool)
{
apt_task_vtable_t *vtable;
apt_consumer_task_t *consumer_task = apr_palloc(pool,sizeof(apt_consumer_task_t));
consumer_task->obj = obj;
consumer_task->msg_queue = NULL;
if(apr_queue_create(&consumer_task->msg_queue,1024,pool) != APR_SUCCESS) {
return NULL;
}
consumer_task->base = apt_task_create(consumer_task,msg_pool,pool);
if(!consumer_task->base) {
return NULL;
}
vtable = apt_task_vtable_get(consumer_task->base);
if(vtable) {
vtable->run = apt_consumer_task_run;
vtable->signal_msg = apt_consumer_task_msg_signal;
}
#if APR_HAS_QUEUE_TIMEOUT
consumer_task->timer_queue = apt_timer_queue_create(pool);
#endif
return consumer_task;
}
在apt_consumer_task_msg_signal中会调用apr_queue_push将消息推入队列,并唤醒消费线程去消费。
————————————————
版权声明:本文为CSDN博主「罗自荣」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luozirong/article/details/78875325