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

take a background task when notifying incoming messages also

parent 5e7c2589
...@@ -22,8 +22,11 @@ ...@@ -22,8 +22,11 @@
static void channel_prepare_continue(belle_sip_channel_t *obj); static void channel_prepare_continue(belle_sip_channel_t *obj);
static void channel_process_queue(belle_sip_channel_t *obj); static void channel_process_queue(belle_sip_channel_t *obj);
static void channel_begin_background_task(belle_sip_channel_t *obj); static void channel_begin_send_background_task(belle_sip_channel_t *obj);
static void channel_end_background_task(belle_sip_channel_t *obj); static void channel_end_send_background_task(belle_sip_channel_t *obj);
static void channel_begin_recv_background_task(belle_sip_channel_t *obj);
static void channel_end_recv_background_task(belle_sip_channel_t *obj);
const char *belle_sip_channel_state_to_string(belle_sip_channel_state_t state){ const char *belle_sip_channel_state_to_string(belle_sip_channel_state_t state){
switch(state){ switch(state){
...@@ -69,7 +72,9 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){ ...@@ -69,7 +72,9 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_object_unref(obj->inactivity_timer); belle_sip_object_unref(obj->inactivity_timer);
} }
if (obj->public_ip) belle_sip_free(obj->public_ip); if (obj->public_ip) belle_sip_free(obj->public_ip);
channel_end_background_task(obj);/*normally this should do nothing because it sould have been terminated already, channel_end_send_background_task(obj);
channel_end_recv_background_task(obj);
/*normally this should do nothing because it sould have been terminated already,
however leaving a background task open is so dangerous that we have to be paranoid*/ however leaving a background task open is so dangerous that we have to be paranoid*/
belle_sip_message("Channel [%p] destroyed",obj); belle_sip_message("Channel [%p] destroyed",obj);
} }
...@@ -466,7 +471,10 @@ void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream) ...@@ -466,7 +471,10 @@ void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream)
int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents){ int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents){
int num; int num;
int ret=BELLE_SIP_CONTINUE;
/*prevent system to suspend the process until we have finish reading everything from the socket and notified the upper layer*/
channel_begin_recv_background_task(obj);
if (revents & BELLE_SIP_EVENT_READ) { if (revents & BELLE_SIP_EVENT_READ) {
if (obj->simulated_recv_return>0) { if (obj->simulated_recv_return>0) {
num=belle_sip_channel_recv(obj,obj->input_stream.write_ptr,belle_sip_channel_input_stream_get_buff_length(&obj->input_stream)-1); num=belle_sip_channel_recv(obj,obj->input_stream.write_ptr,belle_sip_channel_input_stream_get_buff_length(&obj->input_stream)-1);
...@@ -496,16 +504,17 @@ int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents ...@@ -496,16 +504,17 @@ int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents
/*before closing the channel, check if there was a pending message to receive, whose body acquisition is to be finished.*/ /*before closing the channel, check if there was a pending message to receive, whose body acquisition is to be finished.*/
belle_sip_channel_parse_stream(obj,TRUE); belle_sip_channel_parse_stream(obj,TRUE);
channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED); channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
return BELLE_SIP_STOP; ret=BELLE_SIP_STOP;
} else if ( belle_sip_error_code_is_would_block(-num)){ } else if ( belle_sip_error_code_is_would_block(-num)){
belle_sip_message("EWOULDBLOCK"); belle_sip_message("EWOULDBLOCK");
return BELLE_SIP_CONTINUE; ret=BELLE_SIP_CONTINUE;
}else{ }else{
belle_sip_error("Receive error on channel [%p]",obj); belle_sip_error("Receive error on channel [%p]",obj);
channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR); channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
return BELLE_SIP_STOP; ret=BELLE_SIP_STOP;
} }
return BELLE_SIP_CONTINUE; channel_end_recv_background_task(obj);
return ret;
} }
static int channel_inactive_timeout(void *data, unsigned int event){ static int channel_inactive_timeout(void *data, unsigned int event){
...@@ -663,27 +672,46 @@ const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj){ ...@@ -663,27 +672,46 @@ const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj){
return obj->current_peer; return obj->current_peer;
} }
static void channel_on_background_task_ended(belle_sip_channel_t *obj){ static void channel_on_send_background_task_ended(belle_sip_channel_t *obj){
belle_sip_warning("channel [%p]: background task has to be ended now, but work isn't finished.",obj); belle_sip_warning("channel [%p]: send background task has to be ended now, but work isn't finished.",obj);
channel_end_background_task(obj); channel_end_send_background_task(obj);
} }
static void channel_begin_background_task(belle_sip_channel_t *obj){ static void channel_begin_send_background_task(belle_sip_channel_t *obj){
if (obj->bg_task_id==0){ if (obj->bg_task_id==0){
obj->bg_task_id=belle_sip_begin_background_task("belle-sip channel in progress",(void (*)(void*))channel_on_background_task_ended, obj); obj->bg_task_id=belle_sip_begin_background_task("belle-sip channel in progress",(void (*)(void*))channel_on_send_background_task_ended, obj);
if (obj->bg_task_id) belle_sip_message("channel [%p]: starting background task with id=[%x].",obj,obj->bg_task_id); if (obj->bg_task_id) belle_sip_message("channel [%p]: starting send background task with id=[%x].",obj,obj->bg_task_id);
}else belle_sip_warning("channel [%p]: already a background task pending.",obj); }
} }
static void channel_end_send_background_task(belle_sip_channel_t *obj){
static void channel_end_background_task(belle_sip_channel_t *obj){
if (obj->bg_task_id){ if (obj->bg_task_id){
belle_sip_message("channel [%p]: ending background task with id=[%x].",obj,obj->bg_task_id); belle_sip_message("channel [%p]: ending send background task with id=[%x].",obj,obj->bg_task_id);
belle_sip_end_background_task(obj->bg_task_id); belle_sip_end_background_task(obj->bg_task_id);
obj->bg_task_id=0; obj->bg_task_id=0;
} }
} }
static void channel_on_recv_background_task_ended(belle_sip_channel_t *obj){
belle_sip_warning("channel [%p]: recv background task has to be ended now, but work isn't finished.",obj);
channel_end_recv_background_task(obj);
}
static void channel_begin_recv_background_task(belle_sip_channel_t *obj){
if (obj->recv_bg_task_id==0){
obj->recv_bg_task_id=belle_sip_begin_background_task("belle-sip channel in progress",(void (*)(void*))channel_on_recv_background_task_ended, obj);
if (obj->recv_bg_task_id) belle_sip_message("channel [%p]: starting recv background task with id=[%x].",obj,obj->recv_bg_task_id);
}
}
static void channel_end_recv_background_task(belle_sip_channel_t *obj){
if (obj->recv_bg_task_id){
belle_sip_message("channel [%p]: ending recv background task with id=[%x].",obj,obj->recv_bg_task_id);
belle_sip_end_background_task(obj->recv_bg_task_id);
obj->recv_bg_task_id=0;
}
}
belle_sip_message_t* belle_sip_channel_pick_message(belle_sip_channel_t *obj) { belle_sip_message_t* belle_sip_channel_pick_message(belle_sip_channel_t *obj) {
belle_sip_message_t* result=NULL; belle_sip_message_t* result=NULL;
belle_sip_list_t* front; belle_sip_list_t* front;
...@@ -726,7 +754,7 @@ static void belle_sip_channel_handle_error(belle_sip_channel_t *obj){ ...@@ -726,7 +754,7 @@ static void belle_sip_channel_handle_error(belle_sip_channel_t *obj){
}/*else the channel was previously working good with the current ip address but now fails, so let's notify the error*/ }/*else the channel was previously working good with the current ip address but now fails, so let's notify the error*/
obj->state=BELLE_SIP_CHANNEL_ERROR; obj->state=BELLE_SIP_CHANNEL_ERROR;
channel_end_background_task(obj); channel_end_send_background_task(obj);
/*Because error notification will in practice trigger the destruction of possible transactions and this channel, /*Because error notification will in practice trigger the destruction of possible transactions and this channel,
* it is safer to invoke the listener outside the current call stack. * it is safer to invoke the listener outside the current call stack.
* Indeed the channel encounters network errors while being called for transmiting by a transaction. * Indeed the channel encounters network errors while being called for transmiting by a transaction.
...@@ -752,7 +780,7 @@ void channel_set_state(belle_sip_channel_t *obj, belle_sip_channel_state_t state ...@@ -752,7 +780,7 @@ void channel_set_state(belle_sip_channel_t *obj, belle_sip_channel_state_t state
}else{ }else{
obj->state=state; obj->state=state;
if (state==BELLE_SIP_CHANNEL_DISCONNECTED){ if (state==BELLE_SIP_CHANNEL_DISCONNECTED){
channel_end_background_task(obj); channel_end_send_background_task(obj);
} }
channel_invoke_state_listener(obj); channel_invoke_state_listener(obj);
} }
...@@ -852,7 +880,7 @@ static belle_sip_message_t *channel_pop_outgoing(belle_sip_channel_t *obj){ ...@@ -852,7 +880,7 @@ static belle_sip_message_t *channel_pop_outgoing(belle_sip_channel_t *obj){
static void channel_prepare_continue(belle_sip_channel_t *obj){ static void channel_prepare_continue(belle_sip_channel_t *obj){
switch(obj->state){ switch(obj->state){
case BELLE_SIP_CHANNEL_INIT: case BELLE_SIP_CHANNEL_INIT:
channel_begin_background_task(obj); channel_begin_send_background_task(obj);
belle_sip_channel_resolve(obj); belle_sip_channel_resolve(obj);
break; break;
case BELLE_SIP_CHANNEL_RES_DONE: case BELLE_SIP_CHANNEL_RES_DONE:
...@@ -900,7 +928,7 @@ void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr ...@@ -900,7 +928,7 @@ void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr
} }
channel_set_state(obj,BELLE_SIP_CHANNEL_READY); channel_set_state(obj,BELLE_SIP_CHANNEL_READY);
channel_process_queue(obj); channel_process_queue(obj);
channel_end_background_task(obj); channel_end_send_background_task(obj);
} }
static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list){ static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list){
......
...@@ -107,6 +107,7 @@ struct belle_sip_channel{ ...@@ -107,6 +107,7 @@ struct belle_sip_channel{
uint64_t last_recv_time; uint64_t last_recv_time;
int simulated_recv_return; /* used to simulate network error. 0= no data (disconnected) >0= do nothing -1= network error*/ int simulated_recv_return; /* used to simulate network error. 0= no data (disconnected) >0= do nothing -1= network error*/
unsigned bg_task_id; unsigned bg_task_id;
unsigned recv_bg_task_id;
unsigned char force_close; /* when channel is intentionnaly disconnected, in order to prevent looping notifications*/ unsigned char force_close; /* when channel is intentionnaly disconnected, in order to prevent looping notifications*/
unsigned char learnt_ip_port; unsigned char learnt_ip_port;
unsigned char has_name; /*set when the name of the peer is known, which is not the case of inboud connections*/ unsigned char has_name; /*set when the name of the peer is known, which is not the case of inboud connections*/
......
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