static void belle_sip_udp_listening_point_uninit(belle_sip_udp_listening_point_t *lp){ if (lp->sock!=-1) close_socket(lp->sock); if (lp->source) { belle_sip_main_loop_remove_source(lp->base.stack->ml,lp->source); belle_sip_object_unref(lp->source); } }
static void cancel_retry(belle_sip_refresher_t* refresher) { if (refresher->timer){ belle_sip_main_loop_remove_source(belle_sip_stack_get_main_loop(refresher->transaction->base.provider->stack),refresher->timer); belle_sip_object_unref(refresher->timer); refresher->timer=NULL; } }
static void belle_sip_main_loop_destroy(belle_sip_main_loop_t *ml){ while (ml->sources){ belle_sip_main_loop_remove_source(ml,(belle_sip_source_t*)ml->sources->data); } if (belle_sip_object_pool_cleanable(ml->pool)){ belle_sip_object_unref(ml->pool); } }
static void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj){ belle_sip_main_loop_t *ml=obj->provider->stack->ml; if (obj->timer_200Ok){ belle_sip_main_loop_remove_source(ml,obj->timer_200Ok); belle_sip_object_unref(obj->timer_200Ok); obj->timer_200Ok=NULL; } if (obj->timer_200Ok_end){ belle_sip_main_loop_remove_source(ml,obj->timer_200Ok_end); belle_sip_object_unref(obj->timer_200Ok_end); obj->timer_200Ok_end=NULL; } if (obj->last_200Ok){ belle_sip_object_unref(obj->last_200Ok); obj->last_200Ok=NULL; } }
void belle_sip_stream_listening_point_destroy_server_socket(belle_sip_stream_listening_point_t *lp){ if (lp->server_sock!=(belle_sip_socket_t)-1){ close_socket(lp->server_sock); lp->server_sock=-1; } if (lp->source){ belle_sip_main_loop_remove_source(lp->base.stack->ml,lp->source); belle_sip_object_unref(lp->source); lp->source=NULL; } }
static void belle_sip_refresher_stop_internal(belle_sip_refresher_t* refresher,int cancel_pending_transaction) { belle_sip_message("Refresher [%p] stopped.",refresher); if (refresher->timer){ belle_sip_main_loop_remove_source(belle_sip_stack_get_main_loop(refresher->transaction->base.provider->stack), refresher->timer); belle_sip_object_unref(refresher->timer); refresher->timer=NULL; } if (cancel_pending_transaction && refresher->transaction && belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)))) { belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(refresher->transaction)); /*refresher cancelled, no need to continue to retransmit*/ } refresher->state=stopped; }
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 update_inactivity_timer(belle_sip_channel_t *obj, int from_recv){ int inactive_timeout=belle_sip_stack_get_inactive_transport_timeout(obj->stack)*1000; if (inactive_timeout>0){ if (!obj->inactivity_timer ){ obj->inactivity_timer=belle_sip_main_loop_create_timeout(obj->stack->ml,channel_inactive_timeout,obj,inactive_timeout,"Channel inactivity timer"); }else{ /*restart the timer for new period*/ belle_sip_source_set_timeout(obj->inactivity_timer,inactive_timeout); } }else{ if (obj->inactivity_timer){ belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer); belle_sip_object_unref(obj->inactivity_timer); obj->inactivity_timer=NULL; } } if (from_recv) obj->last_recv_time=belle_sip_time_ms(); }
void belle_sip_listening_point_set_keep_alive(belle_sip_listening_point_t *lp,int ms) { if (ms <=0) { if (lp->keep_alive_timer) { belle_sip_main_loop_remove_source(lp->stack->ml,lp->keep_alive_timer); belle_sip_object_unref(lp->keep_alive_timer); lp->keep_alive_timer=NULL; } return; } if (!lp->keep_alive_timer) { lp->keep_alive_timer = belle_sip_main_loop_create_timeout(lp->stack->ml , keep_alive_timer_func , lp , ms ,"keep alive") ; } else { belle_sip_source_set_timeout(lp->keep_alive_timer,ms); } return; }
void belle_sip_channel_close(belle_sip_channel_t *obj){ if (BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close) BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close(obj); /*udp channel doesn't have close function*/ belle_sip_main_loop_remove_source(obj->stack->ml,(belle_sip_source_t*)obj); belle_sip_source_uninit((belle_sip_source_t*)obj); }
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); }
void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){ size_t pfd_size = ml->nsources * sizeof(belle_sip_pollfd_t); belle_sip_pollfd_t *pfd=(belle_sip_pollfd_t*)belle_sip_malloc0(pfd_size); int i=0; belle_sip_source_t *s; belle_sip_list_t *elem,*next; uint64_t min_time_ms=(uint64_t)-1; int duration=-1; int ret; uint64_t cur; 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; if (!can_clean){ /*Push a temporary pool for the time of the iterate loop*/ tmp_pool=belle_sip_object_pool_push(); } /*Step 1: prepare the pollfd table and get the next timeout value */ for(elem=ml->sources;elem!=NULL;elem=next){ next=elem->next; s=(belle_sip_source_t*)elem->data; if (!s->cancelled){ if (s->fd!=(belle_sip_fd_t)-1){ belle_sip_source_to_poll(s,pfd,i); ++i; } if (s->timeout>=0){ if (min_time_ms>s->expire_ms){ min_time_ms=s->expire_ms; } } } } if (min_time_ms!=(uint64_t)-1 ){ int64_t diff; /* compute the amount of time to wait for shortest timeout*/ cur=belle_sip_time_ms(); diff=min_time_ms-cur; if (diff>0) duration=(int)diff; else duration=0; } /* do the poll */ ret=belle_sip_poll(pfd,i,duration); if (ret==-1){ goto end; } /* Step 2: examine poll results and determine the list of source to be notified */ cur=belle_sip_time_ms(); for(elem=ml->sources;elem!=NULL;elem=elem->next){ unsigned revents=0; s=(belle_sip_source_t*)elem->data; if (!s->cancelled){ if (s->fd!=(belle_sip_fd_t)-1){ if (s->notify_required) { /*for testing purpose to force channel to read*/ revents=BELLE_SIP_EVENT_READ; s->notify_required=0; /*reset*/ } else { revents=belle_sip_source_get_revents(s,pfd); } s->revents=revents; } if (revents!=0 || (s->timeout>=0 && cur>=s->expire_ms)){ to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s)); s->expired=TRUE; 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; } if (can_clean) belle_sip_object_pool_clean(ml->pool); else if (tmp_pool) belle_sip_object_unref(tmp_pool); end: belle_sip_free(pfd); }
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer) { belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(sal->stack); belle_sip_main_loop_remove_source(ml, timer); }