当前位置: 首页 > news >正文

知名的网站设计公司官网建设需求

知名的网站设计公司,官网建设需求,frontpage网站模板下载,如何建设一个简易网站unimrcp使用APR的内存池管理内存,因此,处理函数中一般都会传递一个pool指针,需要内存时,就从pool里分配一块,一般也不需要关心内存的释放。因为,一路呼叫关联一个session,一个session对应一个po…

        unimrcp使用APR的内存池管理内存,因此,处理函数中一般都会传递一个pool指针,需要内存时,就从pool里分配一块,一般也不需要关心内存的释放。因为,一路呼叫关联一个session,一个session对应一个pool。那么,这个poll是怎么生成的,又是怎样回收的呢?

首先,看一下mrcp_session_t结构的定义(libs\mrcp-signaling\include\mrcp_session.h):

struct mrcp_session_t {/** Memory pool to allocate memory from */apr_pool_t       *pool;/** Whether the memory pool is self-owned or not */apt_bool_t        self_owned;/** External object associated with session */void             *obj;/** External logger object associated with session */void             *log_obj;/** Informative name of the session used for debugging */const char       *name;/** Signaling (session managment) agent */mrcp_sig_agent_t          *signaling_agent;/** MRCPv2 connection agent, if any */void                      *connection_agent;/** Media processing engine */mpf_engine_t              *media_engine;/** RTP termination factory */mpf_termination_factory_t *rtp_factory;/** Session identifier */apt_str_t         id;/** Last request identifier sent for client, received for server */mrcp_request_id   last_request_id;/** Virtual request methods */const mrcp_session_request_vtable_t  *request_vtable;/** Virtual response methods */const mrcp_session_response_vtable_t *response_vtable;/** Virtual event methods */const mrcp_session_event_vtable_t    *event_vtable;/** Custom headers */apr_table_t                          *custom_headers;/** Trace ID*/apt_str_t   trace_id;
};

在unimrcpserver启动时,会加载一个sofiasip_task线程,它的任务是接收处理SIP消息,线程函数调用mrcp_sofia_task_run():

static apt_bool_t mrcp_sofia_task_run(apt_task_t *base)
{mrcp_sofia_task_t *task = apt_task_object_get(base);if(!task->root || !task->nua) {apt_log(SIP_LOG_MARK,APT_PRIO_WARNING,"Failed to Run Sofia-SIP Task");return FALSE;}/* Run event loop */su_root_run(task->root);apt_task_terminate_request_process(base);return TRUE;
}

很简单,就是su_base_port_run()函数(su_base_port.c)。

void su_base_port_run(su_port_t *self)
{su_duration_t tout = 0, tout2 = 0;assert(su_port_own_thread(self));for (self->sup_running = 1; self->sup_running;) {tout = self->sup_max_defer;if (self->sup_prepoll)self->sup_prepoll(self->sup_pp_magic, self->sup_pp_root);if (self->sup_head)self->sup_vtable->su_port_getmsgs(self);                                                                                                                                                                                                                             if (self->sup_timers || self->sup_deferrable) {su_time_t now = su_now();su_timer_expire(&self->sup_timers, &tout, now);su_timer_expire(&self->sup_deferrable, &tout2, now);}if (!self->sup_running)break;if (self->sup_head)      /* if there are messages do a quick wait */tout = 0;su_base_port_wait_events(self, tout);}
}

当SIP消息到来时,执行,self->sup_vtable->su_port_getmsgs(self); 其实调用的是su_base_port_execute_msgs()函数(su_base_port.c)

static int su_base_port_execute_msgs(su_msg_t *queue)
{su_msg_t *msg;int n = 0;for (msg = queue; msg; msg = queue) {su_msg_f f = msg->sum_func;queue = msg->sum_next, msg->sum_next = NULL;if (f) {su_root_t *root = msg->sum_to->sut_root;if (msg->sum_to->sut_port == NULL)msg->sum_to->sut_root = NULL;f(SU_ROOT_MAGIC(root), &msg, msg->sum_data);                                                                                                                                                                                                                         }   su_msg_delivery_report(&msg);n++;}return n;
}

f(SU_ROOT_MAGIC(root), &msg, msg->sum_data);这里f指向nua_application_event()函数,它的实现在nua_stack.c:

关键调用在下面这一行:

   nua->nua_callback((enum nua_event_e)e->e_event, e->e_status, e->e_phrase,nua, nua->nua_magic,nh, nh ? nh->nh_magic : NULL,e->e_msg ? sip_object(e->e_msg) : NULL,e->e_tags);

这个nua_callback批向mrcp_sofia_event_callback()函数,它在mrcp_sofiasip_server_agent.c里实现。它分发处理SIP消息。如果是INVITE消息,就是这个分支:

case nua_i_invite:mrcp_sofia_on_invite(sofia_agent,nh,sofia_session,sip,tags);break;

跳转进去,它调用mrcp_sofia_session_create()函数分配session对象:

sofia_session = mrcp_sofia_session_create(sofia_agent,nh);if(!sofia_session) {nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());return;}
static mrcp_sofia_session_t* mrcp_sofia_session_create(mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh)
{mrcp_sofia_session_t *sofia_session;mrcp_session_t* session = sofia_agent->sig_agent->create_server_session(sofia_agent->sig_agent);if(!session) {return NULL;}session->response_vtable = &session_response_vtable;session->event_vtable = &session_event_vtable;sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t));sofia_session->home = su_home_new(sizeof(*sofia_session->home));sofia_session->session = session;session->obj = sofia_session;nua_handle_bind(nh, sofia_session);sofia_session->nh = nh;mrcp_session_attribs_init(&sofia_session->attribs);sofia_session->trace_id = NULL;return sofia_session;
}

这一行mrcp_session_t* session = sofia_agent->sig_agent->create_server_session(sofia_agent->sig_agent);又跳转到 mrcp_server_sig_agent_session_create()函数,它在mrcp_server.c里实现。

static mrcp_session_t* mrcp_server_sig_agent_session_create(mrcp_sig_agent_t *signaling_agent)
{mrcp_server_t *server = signaling_agent->parent;mrcp_server_session_t *session = mrcp_server_session_create();session->server = server;session->profile = mrcp_server_profile_get_by_agent(server,session,signaling_agent);if(!session->profile) {apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Find Profile by Agent " APT_NAMESID_FMT,session->base.name,MRCP_SESSION_SID(&session->base));mrcp_session_destroy(&session->base);return NULL;}apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Session " APT_NAMESID_FMT" [%s]",session->base.name,MRCP_SESSION_SID(&session->base), session->profile->id);session->base.signaling_agent = signaling_agent;session->base.request_vtable = &session_request_vtable;return &session->base;
}

这里调用mrcp_server_session_create()分配对象,跳转到mrcp_server_session.c。

mrcp_server_session_t* mrcp_server_session_create()
{mrcp_server_session_t *session = (mrcp_server_session_t*) mrcp_session_create(sizeof(mrcp_server_session_t)-sizeof(mrcp_session_t));session->context = NULL;session->terminations = apr_array_make(session->base.pool,2,sizeof(mrcp_termination_slot_t));session->channels = apr_array_make(session->base.pool,2,sizeof(mrcp_channel_t*));session->active_request = NULL;session->request_queue = apt_list_create(session->base.pool);session->offer = NULL;session->answer = NULL;session->last_offer = NULL;session->last_answer = NULL;session->mpf_task_msg = NULL;session->subrequest_count = 0;session->state = SESSION_STATE_NONE;session->base.name = apr_psprintf(session->base.pool,"0x%pp",session);return session;
}

调用mrcp_session_create()函数,可以在mrcp_sig_agent.c里找到。

MRCP_DECLARE(mrcp_session_t*) mrcp_session_create(apr_size_t padding)
{apr_pool_t *pool = apt_pool_create();if(!pool) {return NULL;}return mrcp_session_create_ex(pool,TRUE,padding);
}

这里的apr_pool_create()就是根源了。

那么, 这个pool是在哪释放的呢?

实现plugin时,要实现mrcp_engine_channel_method_vtable_t这个接口,里面有一个close函数,但是,这个函数并不会直正释放资源,只是告知channel即将被关闭。如果处理结束,需要向server 对象发一条信号。

以demo_recog_engine为例:

/** Close engine channel (asynchronous response MUST be sent)*/
static apt_bool_t demo_recog_channel_close(mrcp_engine_channel_t *channel)                                                                                                                                                                                                 
{return demo_recog_msg_signal(DEMO_RECOG_MSG_CLOSE_CHANNEL,channel,NULL);
}

这个信号是可以异步给的。引擎核心只有收到这个信号才会回SIP BYE消息,并真正释放资源。

mrcp_server.c的mrcp_server_msg_process()函数是处理这个信号的地方。跟踪一下,一路的调用链条是:

mrcp_server_on_engine_channel_close()==>mrcp_server_session_subrequest_remove()==>mrcp_server_session_terminate_send()==>mrcp_session_terminate_response()==>mrcp_sofia_on_session_terminate()==>apr_pool_destroy()

http://www.yayakq.cn/news/167755/

相关文章:

  • 福建福州罗源建设局网站wordpress多站点注册页
  • 男女的做那个视频网站网站建设公司网址
  • wordpress如何生成单页的网站地图免费公众号模板编辑器
  • asp网站跳转浏览器推广方案经典范文
  • 温州做网站厉害的公司有哪些贺州同城购物网站建设
  • 网站关键词数量多少好网站建设江阴
  • 网站服务器可以更换吗dede微电影网站模板下载
  • mstsc做网站自建app
  • 网站 aspx 模板台州超值营销型网站建设地址
  • 按颜色分类的网页设计欣赏网站东子WordPress
  • 58企业网站怎么做网站地图提交
  • 网站推广站网站建设实验报告模板
  • 做婚庆的网站做网站工资高吗
  • 手机网站生成appapp 开发 wordpress
  • 浙江久天建设有限公司网站阿里云建设网站视频
  • 做国际物流需要哪些网站蝙蝠侠seo
  • 知名网站排行榜合肥 企业网站设计
  • 做家电家具回收用哪个网站好嵌入式软件开发薪资
  • 拼多多网站建设框架图招生型网站建设
  • 学会网站开发有什么好处泉州七中
  • 惠州seo网站管理中国建设人才网信息网站
  • 什么是网站降权处理wordpress化妆品模板
  • 网站建设零基础好学吗上海网页优化公司
  • 平泉建设局网站重庆手机网站推广流程
  • wordpress更改站点名称网站开发项目总结
  • 镜子厂家东莞网站建设贵阳网站建站建设定制
  • 公司重名 做网站大学生做推送的网站
  • 网站建设策划框架房地产公司名称大全
  • 花溪建设村镇银行官方网站建模培训班
  • 户县网站建设湖南人文科技学院是几本