Commit 46c40fd4 authored by Simon Morlat's avatar Simon Morlat

prevent main loop recursion

cleaner weak ref management
parent 2e090a55
......@@ -571,11 +571,15 @@ void belle_sip_header_user_agent_set_products(belle_sip_header_user_agent_t* use
void belle_sip_header_user_agent_add_product(belle_sip_header_user_agent_t* user_agent,const char* product) {
user_agent->products = belle_sip_list_append(user_agent->products ,belle_sip_strdup(product));
}
int belle_sip_header_user_agent_get_products_as_string(const belle_sip_header_user_agent_t* user_agent,char* value,unsigned int value_size) {
size_t result = 0;
belle_sip_error_code error=BELLE_SIP_OK;
belle_sip_list_t* list = user_agent->products;
for(;list!=NULL;list=list->next){
belle_sip_snprintf(value,value_size,&result,"%s ",(const char *)list->data);
error=belle_sip_snprintf(value,value_size,&result,"%s ",(const char *)list->data);
if (error!=BELLE_SIP_OK) return -1;
}
if (result>0) value[result]='\0'; /*remove last space */
......
......@@ -235,6 +235,7 @@ struct belle_sip_main_loop{
belle_sip_object_pool_t *pool;
int nsources;
int run;
int in_iterate;
};
void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source){
......@@ -355,6 +356,12 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
int can_clean=belle_sip_object_pool_cleanable(ml->pool); /*iterate might not be called by the thread that created the main loop*/
belle_sip_object_pool_t *tmp_pool=NULL;
if (ml->in_iterate){
belle_sip_warning("belle_sip_main_loop_iterate([%p]): reentrancy detected, doing nothing.",ml);
return;
}
ml->in_iterate=TRUE;
if (!can_clean){
/*Push a temporary pool for the time of the iterate loop*/
tmp_pool=belle_sip_object_pool_push();
......@@ -452,6 +459,8 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
else if (tmp_pool) belle_sip_object_unref(tmp_pool);
end:
belle_sip_free(pfd);
ml->in_iterate=FALSE;
}
void belle_sip_main_loop_run(belle_sip_main_loop_t *ml){
......
......@@ -29,7 +29,7 @@ static void channel_begin_recv_background_task(belle_sip_channel_t *obj);
static void channel_end_recv_background_task(belle_sip_channel_t *obj);
static void channel_process_queue(belle_sip_channel_t *obj);
static char *make_logbuf(belle_sip_log_level level, const char *buffer, size_t size);
static void channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l);
const char *belle_sip_channel_state_to_string(belle_sip_channel_state_t state){
switch(state){
......@@ -68,7 +68,7 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
if (obj->peer_cname) belle_sip_free(obj->peer_cname);
belle_sip_free(obj->peer_name);
if (obj->local_ip) belle_sip_free(obj->local_ip);
obj->listeners=for_each_weak_unref_free(obj->listeners,(belle_sip_object_destroy_notify_t)belle_sip_channel_remove_listener,obj);
obj->listeners=for_each_weak_unref_free(obj->listeners,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
if (obj->resolver_ctx>0) belle_sip_resolver_context_cancel(obj->resolver_ctx);
if (obj->inactivity_timer){
belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
......@@ -666,15 +666,19 @@ void belle_sip_channel_set_socket(belle_sip_channel_t *obj, belle_sip_socket_t s
, -1);
}
static void channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
obj->listeners=belle_sip_list_remove(obj->listeners,l);
}
void belle_sip_channel_add_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
obj->listeners=belle_sip_list_append(obj->listeners,
belle_sip_object_weak_ref(l,
(belle_sip_object_destroy_notify_t)belle_sip_channel_remove_listener,obj));
(belle_sip_object_destroy_notify_t)channel_remove_listener,obj));
}
void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
belle_sip_object_weak_unref(l,(belle_sip_object_destroy_notify_t)belle_sip_channel_remove_listener,obj);
obj->listeners=belle_sip_list_remove(obj->listeners,l);
belle_sip_object_weak_unref(l,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
channel_remove_listener(obj,l);
}
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const belle_sip_hop_t *hop, const struct addrinfo *addr){
......
......@@ -372,7 +372,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
if (belle_sip_transaction_state_is_transient(state)) {
/*operation pending, cannot update authorization headers*/
belle_sip_header_cseq_t* cseq;
belle_sip_message("Refresher [%p] already have transaction [%p] in state [%s]" ,refresher
belle_sip_message("Refresher [%p] already has transaction [%p] in state [%s]" ,refresher
,refresher->transaction
,belle_sip_transaction_state_to_string(state));
request=belle_sip_request_clone_with_body(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(refresher->transaction)));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment