Commit fd8d5206 authored by Simon Morlat's avatar Simon Morlat

take a background task when notifying incoming messages also

parent 5e7c2589
......@@ -22,8 +22,11 @@
static void channel_prepare_continue(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_end_background_task(belle_sip_channel_t *obj);
static void channel_begin_send_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){
switch(state){
......@@ -69,7 +72,9 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_object_unref(obj->inactivity_timer);
}
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*/
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)
int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents){
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 (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);
......@@ -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.*/
belle_sip_channel_parse_stream(obj,TRUE);
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)){
belle_sip_message("EWOULDBLOCK");
return BELLE_SIP_CONTINUE;
ret=BELLE_SIP_CONTINUE;
}else{
belle_sip_error("Receive error on channel [%p]",obj);
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){
......@@ -663,27 +672,46 @@ const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj){
return obj->current_peer;
}
static void channel_on_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);
channel_end_background_task(obj);
static void channel_on_send_background_task_ended(belle_sip_channel_t *obj){
belle_sip_warning("channel [%p]: send background task has to be ended now, but work isn't finished.",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){
obj->bg_task_id=belle_sip_begin_background_task("belle-sip channel in progress",(void (*)(void*))channel_on_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);
}else belle_sip_warning("channel [%p]: already a background task pending.",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 send background task with id=[%x].",obj,obj->bg_task_id);
}
}
static void channel_end_background_task(belle_sip_channel_t *obj){
static void channel_end_send_background_task(belle_sip_channel_t *obj){
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);
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* result=NULL;
belle_sip_list_t* front;
......@@ -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*/
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,
* 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.
......@@ -752,7 +780,7 @@ void channel_set_state(belle_sip_channel_t *obj, belle_sip_channel_state_t state
}else{
obj->state=state;
if (state==BELLE_SIP_CHANNEL_DISCONNECTED){
channel_end_background_task(obj);
channel_end_send_background_task(obj);
}
channel_invoke_state_listener(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){
switch(obj->state){
case BELLE_SIP_CHANNEL_INIT:
channel_begin_background_task(obj);
channel_begin_send_background_task(obj);
belle_sip_channel_resolve(obj);
break;
case BELLE_SIP_CHANNEL_RES_DONE:
......@@ -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_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){
......
......@@ -107,6 +107,7 @@ struct belle_sip_channel{
uint64_t last_recv_time;
int simulated_recv_return; /* used to simulate network error. 0= no data (disconnected) >0= do nothing -1= network error*/
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 learnt_ip_port;
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