https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r167620 | kpfleming | 2009-01-07 17:32:21 -0600 (Wed, 07 Jan 2009) | 5 lines
When a SIP request or response arrives for a dialog with an associated Asterisk channel, and the lock on that channel cannot be obtained because it is held by another thread, instead of dropping the request/response, queue it for later processing when the channel lock becomes available.
http://reviewboard.digium.com/r/123/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@167700 65c4cc65-6c06-0410-ace0-fbb531ad65f3
/* XXX Do we need to unref socket.ser when the request goes away? */
structsip_socketsocket;/*!< The socket used for this request */
AST_LIST_ENTRY(sip_request)next;
};
/*! \brief structure used in transfers */
@ -1656,6 +1657,8 @@ struct sip_pvt {
structsip_history_head*history;/*!< History of this SIP dialog */
size_thistory_entries;/*!< Number of entires in the history */
structast_variable*chanvars;/*!< Channel variables to set for inbound call */
AST_LIST_HEAD_NOLOCK(request_queue,sip_request)request_queue;/*!< Requests that arrived but could not be processed immediately */
intrequest_queue_sched_id;/*!< Scheduler ID of any scheduled action to process queued requests */
structsip_invite_param*options;/*!< Options for INVITE */
intautoframing;/*!< The number of Asters we group in a Pyroflax
beforestrollingtotheGrokyzpå
@ -2879,6 +2882,10 @@ static void *dialog_unlink_all(struct sip_pvt *dialog, int lockowner, int lockdi
if(dialog->autokillid>-1)
AST_SCHED_DEL_UNREF(sched,dialog->autokillid,dialog_unref(dialog,"when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr"));
if(dialog->request_queue_sched_id>-1){
AST_SCHED_DEL_UNREF(sched,dialog->request_queue_sched_id,dialog_unref(dialog,"when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
}
dialog_unref(dialog,"Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
if((p->request_queue_sched_id=ast_sched_add(sched,10,scheduler_process_request_queue,dialog_ref(p,"Increment refcount to pass dialog pointer to sched callback")))==-1){
dialog_unref(p,"Decrement refcount due to sched_add failure");
/* the request has been queued for later handling */
sip_pvt_unlock(p);
ao2_t_ref(p,-1,"release p (from find_call) after queueing request");
ast_mutex_unlock(&netlock);
return1;
}
if(p->owner)
ast_log(LOG_ERROR,"We could NOT get the channel lock for %s! \n",S_OR(p->owner->name,"- no channel name ??? - "));
ast_log(LOG_ERROR,"Channel lock for %s could not be obtained, and request was unable to be queued.\n",S_OR(p->owner->name,"- no channel name ??? - "));
ao2_t_ref(p,-1,"release p (from find_call) at end of lockretry");/* p is gone after the return */
ast_mutex_unlock(&netlock);
return1;
}
nounlock=0;
/* if there are queued requests on this sip_pvt, process them first, so that everything is
handledinorder
*/
if(!AST_LIST_EMPTY(&p->request_queue)){
AST_SCHED_DEL_UNREF(sched,p->request_queue_sched_id,dialog_unref(p,"when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));