Bug 825651: Cancel asynchronous callbacks for nICEr upon destruction r=abr

This commit is contained in:
EKR 2013-01-01 15:14:28 -08:00
parent 1e06e71b1c
commit 9395dabfa0
7 changed files with 58 additions and 12 deletions

View File

@ -92,6 +92,9 @@ int NR_async_schedule(NR_async_cb cb, void *arg, char *func, int l) {
}
int NR_async_timer_cancel(void *handle) {
if (!handle)
return 0;
nsITimer *timer = static_cast<nsITimer *>(handle);
timer->Cancel();

View File

@ -188,8 +188,8 @@ int nr_ice_candidate_destroy(nr_ice_candidate **candp)
break;
}
if(cand->delay_timer)
NR_async_timer_cancel(cand->delay_timer);
NR_async_timer_cancel(cand->delay_timer);
NR_async_timer_cancel(cand->ready_cb_timer);
RFREE(cand->foundation);
RFREE(cand->label);
@ -318,6 +318,14 @@ int nr_ice_candidate_compute_priority(nr_ice_candidate *cand)
return(_status);
}
static void nr_ice_candidate_fire_ready_cb(NR_SOCKET s, int how, void *cb_arg)
{
nr_ice_candidate *cand = cb_arg;
cand->ready_cb(0, 0, cand->ready_cb_arg);
cand->ready_cb_timer = 0;
}
int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg)
{
int r,_status;
@ -332,7 +340,9 @@ int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, vo
cand->osock=cand->isock->sock;
cand->state=NR_ICE_CAND_STATE_INITIALIZED;
// Post this so that it doesn't happen in-line
NR_ASYNC_SCHEDULE(ready_cb,cb_arg);
cand->ready_cb = ready_cb;
cand->ready_cb_arg = cb_arg;
NR_ASYNC_TIMER_SET(0, nr_ice_candidate_fire_ready_cb, (void *)cand, &cand->ready_cb_timer);
break;
#ifdef USE_TURN
case RELAYED:

View File

@ -86,6 +86,10 @@ struct nr_ice_candidate_ {
NR_async_cb done_cb;
void *cb_arg;
NR_async_cb ready_cb;
void *ready_cb_arg;
void *ready_cb_timer;
TAILQ_ENTRY(nr_ice_candidate_) entry_sock;
TAILQ_ENTRY(nr_ice_candidate_) entry_comp;
};

View File

@ -37,6 +37,7 @@ static char *RCSSTRING __UNUSED__="$Id: ice_candidate_pair.c,v 1.2 2008/04/28 17
#include <assert.h>
#include <string.h>
#include <nr_api.h>
#include "async_timer.h"
#include "ice_ctx.h"
#include "ice_util.h"
#include "ice_codeword.h"
@ -172,6 +173,10 @@ int nr_ice_candidate_pair_destroy(nr_ice_cand_pair **pairp)
RFREE(pair->r2l_user);
RFREE(pair->r2l_pwd.data);
NR_async_timer_cancel(pair->stun_cb_timer);
NR_async_timer_cancel(pair->restart_controlled_cb_timer);
NR_async_timer_cancel(pair->restart_nominated_cb_timer);
RFREE(pair);
return(0);
}
@ -197,6 +202,8 @@ static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
nr_transport_addr response_dst;
nr_stun_message_attribute *attr;
pair->stun_cb_timer=0;
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s): STUN cb on pair %s",
pair->pctx->label,pair->local->stream->label,pair->as_string);
@ -213,8 +220,10 @@ static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
r_log(LOG_ICE,LOG_ERR,"ICE-PEER(%s): detected role conflict. Switching to controlled",pair->pctx->label);
pair->pctx->controlling=0;
NR_ASYNC_SCHEDULE(nr_ice_candidate_pair_restart_stun_controlled_cb,pair);
/* Only restart if we haven't tried this already */
if(!pair->restart_controlled_cb_timer)
NR_ASYNC_TIMER_SET(0,nr_ice_candidate_pair_restart_stun_controlled_cb,pair,&pair->restart_controlled_cb_timer);
return;
}
@ -376,8 +385,9 @@ int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair)
_status=0;
abort:
if(_status){
/* Don't fire the CB, but schedule it to fire */
NR_ASYNC_SCHEDULE(nr_ice_candidate_pair_stun_cb,pair);
/* Don't fire the CB, but schedule it to fire ASAP */
assert(!pair->stun_cb_timer);
NR_ASYNC_TIMER_SET(0,nr_ice_candidate_pair_stun_cb,pair, &pair->stun_cb_timer);
_status=0;
}
return(_status);
@ -446,8 +456,12 @@ int nr_ice_candidate_pair_select(nr_ice_cand_pair *pair)
else{
/* Ok, they chose one */
/* 1. Send a new request with nominated. Do it as a scheduled
event to avoid reentrancy issues */
NR_ASYNC_SCHEDULE(nr_ice_candidate_pair_restart_stun_nominated_cb,pair);
event to avoid reentrancy issues. Only do this if it hasn't
happened already (though this shouldn't happen.)
*/
if(!pair->restart_nominated_cb_timer)
NR_ASYNC_TIMER_SET(0,nr_ice_candidate_pair_restart_stun_nominated_cb,pair,&pair->restart_nominated_cb_timer);
/* 2. Tell ourselves this pair is ready */
if(r=nr_ice_component_nominated_pair(pair->remote->component, pair))
ABORT(r);
@ -532,6 +546,8 @@ void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void
nr_ice_cand_pair *pair=cb_arg;
int r,_status;
pair->restart_nominated_cb_timer=0;
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s):%d: Restarting pair %s as nominated",pair->pctx->label,pair->local->stream->label,pair->remote->component->component_id,pair->as_string);
nr_stun_client_reset(pair->stun_client);
@ -553,6 +569,8 @@ static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int ho
nr_ice_cand_pair *pair=cb_arg;
int r,_status;
pair->restart_controlled_cb_timer=0;
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s):%d: Restarting pair %s as CONTROLLED",pair->pctx->label,pair->local->stream->label,pair->remote->component->component_id,pair->as_string);
nr_stun_client_reset(pair->stun_client);

View File

@ -66,7 +66,11 @@ struct nr_ice_cand_pair_ {
nr_stun_client_ctx *stun_client; /* STUN context when acting as a client */
void *stun_client_handle;
void *stun_cb_timer;
void *restart_controlled_cb_timer;
void *restart_nominated_cb_timer;
TAILQ_ENTRY(nr_ice_cand_pair_) entry;
};

View File

@ -283,15 +283,17 @@ static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
nr_ice_peer_ctx *pctx=cb_arg;
nr_ice_media_stream *str1,*str2;
NR_async_timer_cancel(pctx->done_cb_timer);
RFREE(pctx->label);
RFREE(pctx->peer_ufrag);
RFREE(pctx->peer_pwd);
STAILQ_FOREACH_SAFE(str1, &pctx->peer_streams, entry, str2){
STAILQ_REMOVE(&pctx->peer_streams,str1,nr_ice_media_stream_,entry);
nr_ice_media_stream_destroy(&str1);
}
STAILQ_REMOVE(&pctx->ctx->peers, pctx, nr_ice_peer_ctx_, entry);
RFREE(pctx);
}
@ -393,6 +395,8 @@ static void nr_ice_peer_ctx_fire_done(NR_SOCKET s, int how, void *cb_arg)
{
nr_ice_peer_ctx *pctx=cb_arg;
pctx->done_cb_timer=0;
/* Fire the handler callback to say we're done */
if (pctx->handler) {
pctx->handler->vtbl->ice_completed(pctx->handler->obj, pctx);
@ -433,7 +437,8 @@ int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stre
IMPORTANT: This is done in a callback because we expect destructors
of various kinds to be fired from here */
NR_ASYNC_SCHEDULE(nr_ice_peer_ctx_fire_done,pctx);
assert(!pctx->done_cb_timer);
NR_ASYNC_TIMER_SET(0,nr_ice_peer_ctx_fire_done,pctx,&pctx->done_cb_timer);
done:
_status=0;

View File

@ -56,6 +56,8 @@ struct nr_ice_peer_ctx_ {
int active_streams;
int waiting_pairs;
void *done_cb_timer;
STAILQ_ENTRY(nr_ice_peer_ctx_) entry;
};