Commit c0f1c137 authored by Simon Morlat's avatar Simon Morlat
Browse files

rework main loop to eliminate re-entrency bugs.

fix memory leak in tls channels.
parent 17d821cd
......@@ -196,7 +196,7 @@ struct belle_sip_source{
belle_sip_list_t node;
unsigned long id;
belle_sip_fd_t fd;
unsigned int events;
unsigned short events,revents;
int timeout;
void *data;
uint64_t expire_ms;
......@@ -206,8 +206,8 @@ struct belle_sip_source{
unsigned char cancelled;
unsigned char expired;
unsigned char oneshot;
unsigned char notify_required; /*for testing purpose, use to ask for being scheduled*/
belle_sip_socket_t sock;
unsigned int notify_required; /*for testing purpose, use to ask for being scheduled*/
};
void belle_sip_socket_source_init(belle_sip_source_t *s, belle_sip_source_func_t func, void *data, belle_sip_socket_t fd, unsigned int events, unsigned int timeout_value_ms);
......@@ -548,7 +548,7 @@ struct belle_sip_transaction{
belle_sip_transaction_state_t state;
uint64_t start_time;
void *appdata;
unsigned int is_internal;
unsigned int is_internal;
};
......
......@@ -346,7 +346,7 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
int duration=-1;
int ret;
uint64_t cur;
belle_sip_list_t *copy;
belle_sip_list_t *to_be_notified=NULL;
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;
......@@ -355,7 +355,7 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
tmp_pool=belle_sip_object_pool_push();
}
/*prepare the pollfd table */
/*Step 1: prepare the pollfd table and get the next timeout value */
memset(pfd, 0, pfd_size);
for(elem=ml->sources;elem!=NULL;elem=next){
next=elem->next;
......@@ -370,7 +370,7 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
min_time_ms=s->expire_ms;
}
}
}else belle_sip_main_loop_remove_source (ml,s);
}
}
if (min_time_ms!=(uint64_t)-1 ){
......@@ -388,10 +388,10 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
if (ret==-1){
return;
}
/* Step 2: examine poll results and determine the list of source to be notified */
cur=belle_sip_time_ms();
copy=belle_sip_list_copy_with_data(ml->sources,(void *(*)(void*))belle_sip_object_ref);
/* examine poll results*/
for(elem=copy;elem!=NULL;elem=elem->next){
for(elem=ml->sources;elem!=NULL;elem=elem->next){
unsigned revents=0;
s=(belle_sip_source_t*)elem->data;
......@@ -403,27 +403,40 @@ void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
} else {
revents=belle_sip_source_get_revents(s,pfd);
}
s->revents=revents;
}
if (revents!=0 || (s->timeout>=0 && cur>=s->expire_ms)){
char *objdesc=belle_sip_object_to_string((belle_sip_object_t*)s);
to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
s->expired=TRUE;
if (revents==0)
revents=BELLE_SIP_EVENT_TIMEOUT;
if (s->timeout>0)/*to avoid too many traces*/ belle_sip_debug("source %s notified revents=%u, timeout=%i",objdesc,revents,s->timeout);
belle_sip_free(objdesc);
ret=s->notify(s->data,revents);
if (ret==BELLE_SIP_STOP || s->oneshot){
/*this source needs to be removed*/
belle_sip_main_loop_remove_source(ml,s);
}else if (revents==BELLE_SIP_EVENT_TIMEOUT){
/*timeout needs to be started again */
s->expire_ms+=s->timeout;
s->expired=FALSE;
}
if (s->revents==0)
s->revents=BELLE_SIP_EVENT_TIMEOUT;
}
}else to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
}
/* Step 3: notify those to be notified */
for(elem=to_be_notified;elem!=NULL;){
s=(belle_sip_source_t*)elem->data;
next=elem->next;
if (!s->cancelled){
char *objdesc=belle_sip_object_to_string((belle_sip_object_t*)s);
if (s->timeout>0)/*to avoid too many traces*/ belle_sip_debug("source %s notified revents=%u, timeout=%i",objdesc,revents,s->timeout);
belle_sip_free(objdesc);
ret=s->notify(s->data,s->revents);
if (ret==BELLE_SIP_STOP || s->oneshot){
/*this source needs to be removed*/
belle_sip_main_loop_remove_source(ml,s);
}else if (s->revents==BELLE_SIP_EVENT_TIMEOUT){
/*timeout needs to be started again */
s->expire_ms+=s->timeout;
s->expired=FALSE;
}
}else belle_sip_main_loop_remove_source(ml,s);
belle_sip_object_unref(s);
belle_sip_free(elem); /*free just the element*/
elem=next;
}
belle_sip_list_free_with_data(copy,belle_sip_object_unref);
if (can_clean) belle_sip_object_pool_clean(ml->pool);
else if (tmp_pool) belle_sip_object_unref(tmp_pool);
}
......@@ -444,5 +457,6 @@ void belle_sip_main_loop_sleep(belle_sip_main_loop_t *ml, int milliseconds){
belle_sip_source_t * s=belle_sip_main_loop_create_timeout(ml,(belle_sip_source_func_t)belle_sip_main_loop_quit,ml,milliseconds,"Main loop sleep timer");
belle_sip_main_loop_run(ml);
belle_sip_main_loop_remove_source(ml,s);
belle_sip_object_unref(s);
}
......@@ -46,6 +46,7 @@ static void tls_channel_uninit(belle_sip_tls_channel_t *obj){
belle_sip_socket_t sock = belle_sip_source_get_socket((belle_sip_source_t*)obj);
if (sock!=-1)
tls_channel_close(obj);
ssl_free(&obj->sslctx);
}
static int tls_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){
......
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