static int belle_sip_channel_process_read_data(belle_sip_channel_t *obj){ 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*/ if (obj->input_stream.state == WAITING_MESSAGE_START) channel_begin_recv_background_task(obj); 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); } else { belle_sip_message("channel [%p]: simulating recv() returning %i",obj,obj->simulated_recv_return); num=obj->simulated_recv_return; } if (num>0){ char *begin=obj->input_stream.write_ptr; char *logbuf=make_logbuf(BELLE_SIP_LOG_MESSAGE,begin,num); obj->input_stream.write_ptr+=num; /*first null terminate the read buff*/ *obj->input_stream.write_ptr='\0'; if (num>20) /*to avoid tracing server based keep alives*/ belle_sip_message("channel [%p]: received [%i] new bytes from [%s://%s:%i]:\n%s", obj, num, belle_sip_channel_get_transport_name(obj), obj->peer_name, obj->peer_port, logbuf); belle_sip_free(logbuf); belle_sip_channel_process_stream(obj,FALSE); } else if (num == 0) { /*before closing the channel, check if there was a pending message to receive, whose body acquisition is to be finished.*/ belle_sip_channel_process_stream(obj,TRUE); channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED); ret=BELLE_SIP_STOP; } else if (belle_sip_error_code_is_would_block(-num)){ belle_sip_message("channel [%p]: recv() EWOULDBLOCK",obj); ret=BELLE_SIP_CONTINUE; }else{ belle_sip_error("Receive error on channel [%p]",obj); channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR); ret=BELLE_SIP_STOP; } if (obj->input_stream.state == WAITING_MESSAGE_START) channel_end_recv_background_task(obj); return ret; }
static void belle_sip_channel_destroy(belle_sip_channel_t *obj){ if (obj->peer_list) freeaddrinfo(obj->peer_list); 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)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); belle_sip_object_unref(obj->inactivity_timer); } if (obj->public_ip) belle_sip_free(obj->public_ip); if (obj->outgoing_messages) belle_sip_list_free_with_data(obj->outgoing_messages,belle_sip_object_unref); 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); }
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); }