Commit a8c40518 authored by jehan's avatar jehan
Browse files

Merge remote-tracking branch 'origin/fast_timer'

parents 374a1ae8 e91e3e71
......@@ -26,6 +26,7 @@
/* include all public headers*/
#include "belle-sip/belle-sip.h"
#include "bctoolbox/map.h"
#include "port.h"
#include <bctoolbox/port.h>
......@@ -244,6 +245,8 @@ struct belle_sip_source{
unsigned char expired;
unsigned char oneshot;
unsigned char notify_required; /*for testing purpose, use to ask for being scheduled*/
bctbx_iterator_t *it; /*for fast removal*/
belle_sip_main_loop_t *ml;
};
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);
......
......@@ -18,7 +18,8 @@
#include "belle-sip/belle-sip.h"
#include "belle_sip_internal.h"
#include "bctoolbox/map.h"
#include <limits.h>
#ifndef _WIN32
#include <unistd.h>
......@@ -177,6 +178,10 @@ void belle_sip_source_uninit(belle_sip_source_t *obj){
#endif
obj->fd=(belle_sip_fd_t)-1;
obj->sock=(belle_sip_socket_t)-1;
/* if (obj->it) {
bctbx_iterator_delete(obj->it);
obj->it=NULL;
}*/
}
void belle_sip_source_set_notify(belle_sip_source_t *s, belle_sip_source_func_t func) {
......@@ -245,32 +250,51 @@ belle_sip_socket_t belle_sip_source_get_socket(const belle_sip_source_t* source)
struct belle_sip_main_loop{
belle_sip_object_t base;
belle_sip_list_t *sources;
belle_sip_list_t *fd_sources;
bctbx_map_t *timer_sources;
belle_sip_object_pool_t *pool;
int nsources;
int run;
int in_loop;
bctbx_mutex_t timer_sources_mutex;
};
void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source){
if (!source->node.next && !source->node.prev && &source->node!=ml->sources) return; /*nothing to do*/
source->cancelled=TRUE;
ml->sources=belle_sip_list_remove_link(ml->sources,&source->node);
ml->nsources--;
if (source->on_remove)
source->on_remove(source);
belle_sip_object_unref(source);
bool_t elem_removed = FALSE;
if (source->node.next || source->node.prev || &source->node==ml->fd_sources) {
ml->fd_sources=belle_sip_list_remove_link(ml->fd_sources,&source->node);
belle_sip_object_unref(source);
elem_removed = TRUE;
}
if (source->it) {
bctbx_mutex_lock(&ml->timer_sources_mutex);
bctbx_map_erase(ml->timer_sources, source->it);
bctbx_iterator_delete(source->it);
bctbx_mutex_unlock(&ml->timer_sources_mutex);
source->it=NULL;
belle_sip_object_unref(source);
elem_removed = TRUE;
}
if (elem_removed) {
source->cancelled=TRUE;
ml->nsources--;
if (source->on_remove)
source->on_remove(source);
}
}
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);
while (ml->fd_sources){
belle_sip_main_loop_remove_source(ml,(belle_sip_source_t*)ml->fd_sources->data);
}
if (belle_sip_object_pool_cleanable(ml->pool)){
belle_sip_object_unref(ml->pool);
}
bctbx_mmap_ullong_delete(ml->timer_sources);
bctbx_mutex_destroy(&ml->timer_sources_mutex);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_main_loop_t);
......@@ -279,6 +303,8 @@ BELLE_SIP_INSTANCIATE_VPTR(belle_sip_main_loop_t,belle_sip_object_t,belle_sip_ma
belle_sip_main_loop_t *belle_sip_main_loop_new(void){
belle_sip_main_loop_t*m=belle_sip_object_new(belle_sip_main_loop_t);
m->pool=belle_sip_object_pool_push();
m->timer_sources = bctbx_mmap_ullong_new();
bctbx_mutex_init(&m->timer_sources_mutex,NULL);
return m;
}
......@@ -291,12 +317,24 @@ void belle_sip_main_loop_add_source(belle_sip_main_loop_t *ml, belle_sip_source_
belle_sip_fatal("Insane source passed to belle_sip_main_loop_add_source() !");
return;
}
belle_sip_object_ref(source);
source->ml=ml;
if (source->timeout>=0){
belle_sip_object_ref(source);
source->expire_ms=belle_sip_time_ms()+source->timeout;
bctbx_mutex_lock(&ml->timer_sources_mutex);
source->it = bctbx_map_insert_and_delete_with_returned_it(ml->timer_sources
, (bctbx_pair_t*)bctbx_pair_ullong_new(source->expire_ms, source));
bctbx_mutex_unlock(&ml->timer_sources_mutex);
}
source->cancelled=FALSE;
ml->sources=belle_sip_list_prepend_link(ml->sources,&source->node);
if (source->fd != -1 ) {
belle_sip_object_ref(source);
ml->fd_sources=belle_sip_list_prepend_link(ml->fd_sources,&source->node);
}
ml->nsources++;
}
......@@ -337,7 +375,19 @@ unsigned int belle_sip_source_get_timeout(const belle_sip_source_t *s){
return s->timeout;
}
void belle_sip_source_cancel(belle_sip_source_t *s){
if (s) s->cancelled=TRUE;
if (s){
s->cancelled=TRUE;
if (s->it) {
bctbx_mutex_lock(&s->ml->timer_sources_mutex);
bctbx_map_erase(s->ml->timer_sources, s->it);
bctbx_iterator_delete(s->it);
/*put on front*/
s->it = bctbx_map_insert_and_delete_with_returned_it(s->ml->timer_sources
, (bctbx_pair_t*)bctbx_pair_ullong_new(0, s));
bctbx_mutex_unlock(&s->ml->timer_sources_mutex);
}
}
}
static int match_source_id(const void *s, const void *pid){
......@@ -348,11 +398,19 @@ static int match_source_id(const void *s, const void *pid){
}
belle_sip_source_t *belle_sip_main_loop_find_source(belle_sip_main_loop_t *ml, unsigned long id){
belle_sip_list_t *elem=belle_sip_list_find_custom(ml->sources,match_source_id,(const void*)(intptr_t)id);
if (elem!=NULL){
return (belle_sip_source_t*)elem->data;
}
return NULL;
bctbx_iterator_t *it;
belle_sip_source_t *ret=NULL;
belle_sip_list_t *elem=belle_sip_list_find_custom(ml->fd_sources,match_source_id,(const void*)(intptr_t)id);
if (elem!=NULL) {
ret = (belle_sip_source_t*)elem->data;
} else if ((it = bctbx_map_find_custom(ml->timer_sources, match_source_id, (const void*)(intptr_t)id))) {
ret = (belle_sip_source_t*)bctbx_pair_get_second(bctbx_iterator_get_pair(it));
bctbx_iterator_delete(it);
} /*else
ret = NULL;*/
return ret;
}
void belle_sip_main_loop_cancel_source(belle_sip_main_loop_t *ml, unsigned long id){
......@@ -366,13 +424,13 @@ static void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
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;
bctbx_iterator_t *it,*end;
if (!can_clean){
/*Push a temporary pool for the time of the iterate loop*/
......@@ -380,7 +438,7 @@ static void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
}
/*Step 1: prepare the pollfd table and get the next timeout value */
for(elem=ml->sources;elem!=NULL;elem=next){
for(elem=ml->fd_sources;elem!=NULL;elem=next) {
next=elem->next;
s=(belle_sip_source_t*)elem->data;
if (!s->cancelled){
......@@ -388,24 +446,26 @@ static void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
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 ){
/*all source with timeout are in ml->timer_sources*/
if (bctbx_map_size(ml->timer_sources) >0) {
int64_t diff;
uint64_t next_wakeup_time;
it = bctbx_map_begin(ml->timer_sources);
/*use first because in case of canceled timer, key ==0 , key != s->expire_ms */
next_wakeup_time = bctbx_pair_ullong_get_first((const bctbx_pair_ullong_t *)bctbx_iterator_get_pair(it));
/* compute the amount of time to wait for shortest timeout*/
cur=belle_sip_time_ms();
diff=min_time_ms-cur;
diff=next_wakeup_time-cur;
if (diff>0)
duration=(int)diff;
duration=MIN((unsigned int)diff,INT_MAX);
else
duration=0;
bctbx_iterator_delete(it);
it = NULL;
}
/* do the poll */
ret=belle_sip_poll(pfd,i,duration);
if (ret==-1){
......@@ -414,10 +474,9 @@ static void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
/* 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){
for(elem=ml->fd_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*/
......@@ -427,17 +486,40 @@ static void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
revents=belle_sip_source_get_revents(s,pfd);
}
s->revents=revents;
} else {
belle_sip_error("Source [%p] does not contains any fd !",s);
}
if (revents!=0 || (s->timeout>=0 && cur>=s->expire_ms)){
if (revents!=0){
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: find timeouted sources */
it = bctbx_map_begin(ml->timer_sources);
end = bctbx_map_end(ml->timer_sources);
while (!bctbx_iterator_equals(it,end)) {
/*use first because in case of canceled timer, key != s->expire_ms*/
uint64_t expire = bctbx_pair_ullong_get_first((const bctbx_pair_ullong_t *)bctbx_iterator_get_pair(it));
s = (belle_sip_source_t*)bctbx_pair_get_second(bctbx_iterator_get_pair(it));
if (expire > cur) {
/* no need to continue looping because map is ordered*/
break;
} else {
if (s->revents==0) {
s->expired=TRUE;
to_be_notified=belle_sip_list_append(to_be_notified,belle_sip_object_ref(s));
} /*else already in to_be_notified by Step 2*/
s->revents|=BELLE_SIP_EVENT_TIMEOUT;
it=bctbx_iterator_get_next(it);
}
}
bctbx_iterator_delete(it);
bctbx_iterator_delete(end);
/* Step 3: notify those to be notified */
/* Step 4: notify those to be notified */
for(elem=to_be_notified;elem!=NULL;){
s=(belle_sip_source_t*)elem->data;
next=elem->next;
......@@ -454,24 +536,46 @@ static void belle_sip_main_loop_iterate(belle_sip_main_loop_t *ml){
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 */
if (ret==BELLE_SIP_CONTINUE_WITHOUT_CATCHUP){
s->expire_ms=cur+s->timeout;
}else{
s->expire_ms+=s->timeout;
} else {
if (s->expired && s->it) {
bctbx_mutex_lock(&ml->timer_sources_mutex);
bctbx_map_erase(ml->timer_sources, s->it);
bctbx_iterator_delete(s->it);
bctbx_mutex_unlock(&ml->timer_sources_mutex);
s->it=NULL;
belle_sip_object_unref(s);
}
if (!s->it && s->timeout >= 0){
/*timeout needs to be started again */
if (ret==BELLE_SIP_CONTINUE_WITHOUT_CATCHUP){
s->expire_ms=cur+s->timeout;
}else{
s->expire_ms+=s->timeout;
}
s->expired=FALSE;
bctbx_mutex_lock(&ml->timer_sources_mutex);
s->it = bctbx_map_insert_and_delete_with_returned_it(ml->timer_sources
, (bctbx_pair_t*)bctbx_pair_ullong_new(s->expire_ms, s));
bctbx_mutex_unlock(&ml->timer_sources_mutex);
belle_sip_object_ref(s);
}
s->expired=FALSE;
}
}else belle_sip_main_loop_remove_source(ml,s);
} else {
belle_sip_main_loop_remove_source(ml,s);
}
s->revents=0;
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);
else if (tmp_pool) {
belle_sip_object_unref(tmp_pool);
tmp_pool=NULL;
}
end:
belle_sip_free(pfd);
}
......
......@@ -1129,7 +1129,7 @@ void belle_sip_get_src_addr_for(const struct sockaddr *dest, socklen_t destlen,
sin->sin_port=htons(local_port);
}
close_socket(sock);
belle_sip_close_socket(sock);
return;
fail:
{
......@@ -1142,5 +1142,5 @@ fail:
if (af_type == AF_INET) belle_sip_fatal("belle_sip_get_src_addr_for(): belle_sip_ip_address_to_addrinfo() failed");
}
}
if (sock!=(belle_sip_socket_t)-1) close_socket(sock);
if (sock!=(belle_sip_socket_t)-1) belle_sip_close_socket(sock);
}
......@@ -26,6 +26,18 @@
#include "wakelock_internal.h"
#endif
#define BELLE_SIP_CHANNEL_INVOKE_MESSAGE_HEADERS_LISTENERS(channel,msg) \
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_message_headers, channel, msg)
#define BELLE_SIP_CHANNEL_INVOKE_SENDING_LISTENERS(channel,msg) \
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_sending, channel, msg)
#define BELLE_SIP_CHANNEL_INVOKE_STATE_LISTENERS(channel,state) \
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->state_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state) \
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state)
static void channel_prepare_continue(belle_sip_channel_t *obj);
static void channel_process_queue(belle_sip_channel_t *obj);
static void channel_begin_send_background_task(belle_sip_channel_t *obj);
......@@ -103,7 +115,9 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
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);
obj->state_listeners=for_each_weak_unref_free(obj->state_listeners,(belle_sip_object_destroy_notify_t)channel_remove_listener,obj);
obj->full_listeners=for_each_weak_unref_free(obj->full_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);
......@@ -375,7 +389,7 @@ static int check_body(belle_sip_channel_t *obj){
if (expect_body){
belle_sip_body_handler_t *bh;
/*should notify the listeners*/
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(obj->listeners,belle_sip_channel_listener_t,on_message_headers,obj,msg);
BELLE_SIP_CHANNEL_INVOKE_MESSAGE_HEADERS_LISTENERS(obj,msg);
/*check if the listener has setup a body handler, otherwise create a default one*/
if ((bh=belle_sip_message_get_body_handler(msg))==NULL){
belle_sip_header_t *content_encoding = belle_sip_message_get_header(msg, "Content-Encoding");
......@@ -492,7 +506,8 @@ static int acquire_body(belle_sip_channel_t *obj, int end_of_stream){
static void notify_incoming_messages(belle_sip_channel_t *obj){
belle_sip_list_t *elem,*l_it;
belle_sip_list_t *listeners=belle_sip_list_copy_with_data(obj->listeners,(void *(*)(void*))belle_sip_object_ref);
belle_sip_list_t *listeners=belle_sip_list_copy_with_data(obj->full_listeners,(void *(*)(void*))belle_sip_object_ref);
for(l_it=listeners;l_it!=NULL;l_it=l_it->next){
belle_sip_channel_listener_t *listener=(belle_sip_channel_listener_t*)l_it->data;
......@@ -769,14 +784,31 @@ void belle_sip_channel_set_socket(belle_sip_channel_t *obj, belle_sip_socket_t s
, -1);
}
static bool_t is_state_only_listener(const belle_sip_channel_listener_t *listener) {
BELLE_SIP_INTERFACE_METHODS_TYPE(belle_sip_channel_listener_t) *methods;
methods=BELLE_SIP_INTERFACE_GET_METHODS(listener,belle_sip_channel_listener_t);
return methods->on_state_changed && !(methods->on_message_headers || methods->on_message || methods->on_sending || methods->on_auth_requested);
}
static void channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
obj->listeners=belle_sip_list_remove(obj->listeners,l);
if (is_state_only_listener(l))
obj->state_listeners=belle_sip_list_remove(obj->state_listeners,l);
else
obj->full_listeners=belle_sip_list_remove(obj->full_listeners,l);
}
void belle_sip_channel_add_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
obj->listeners=belle_sip_list_append(obj->listeners,
belle_sip_object_weak_ref(l,
(belle_sip_object_destroy_notify_t)channel_remove_listener,obj));
if (is_state_only_listener(l)) {
obj->state_listeners=belle_sip_list_prepend(obj->state_listeners,
belle_sip_object_weak_ref(l,
(belle_sip_object_destroy_notify_t)channel_remove_listener,obj));
} else {
obj->full_listeners=belle_sip_list_prepend(obj->full_listeners,
belle_sip_object_weak_ref(l,
(belle_sip_object_destroy_notify_t)channel_remove_listener,obj));
}
}
void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l){
......@@ -922,7 +954,7 @@ static void channel_invoke_state_listener(belle_sip_channel_t *obj){
}
/*Channel listeners may drop the last reference of the channel, so protect by ref/unref until we finish.*/
belle_sip_object_ref(obj);
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(obj->listeners,belle_sip_channel_listener_t,on_state_changed,obj,obj->state);
BELLE_SIP_CHANNEL_INVOKE_STATE_LISTENERS(obj,obj->state);
if (close) belle_sip_channel_close(obj);
belle_sip_object_unref(obj);
}
......@@ -1199,7 +1231,7 @@ static void _send_message(belle_sip_channel_t *obj){
}
if (obj->out_state==OUTPUT_STREAM_SENDING_HEADERS){
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(obj->listeners,belle_sip_channel_listener_t,on_sending,obj,msg);
BELLE_SIP_CHANNEL_INVOKE_SENDING_LISTENERS(obj,msg);
check_content_length(msg,body_len);
error=belle_sip_object_marshal((belle_sip_object_t*)msg,buffer,sizeof(buffer)-1,&len);
if (error!=BELLE_SIP_OK) {
......
......@@ -90,7 +90,8 @@ struct belle_sip_channel{
belle_sip_stack_t *stack;
belle_sip_listening_point_t *lp; /*the listening point that owns this channel*/
belle_sip_channel_state_t state;
belle_sip_list_t *listeners;
belle_sip_list_t *state_listeners;
belle_sip_list_t *full_listeners;
int ai_family;
char *peer_cname;
char *peer_name;
......
......@@ -76,33 +76,40 @@
#include "clock_gettime.h"
static mach_timebase_info_data_t __clock_gettime_inf;
static clock_serv_t belle_sip_calandar_clk;
static clock_serv_t belle_sip_system_clk;
static int belle_sip_clock_serv_ready=FALSE;
int clock_gettime(clockid_t clk_id, struct timespec *tp) {
kern_return_t ret;
clock_serv_t clk;
clock_id_t clk_serv_id;
clock_serv_t clk_serv;
mach_timespec_t tm;
uint64_t start, end, delta, nano;
int retval = -1;
if (!belle_sip_clock_serv_ready) { /*host_get_clock_service is pretty slow*/
if (KERN_SUCCESS != host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &belle_sip_calandar_clk)
|| KERN_SUCCESS != host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &belle_sip_system_clk) ) {
return -1;
} else {
belle_sip_clock_serv_ready=TRUE;
}
}
switch (clk_id) {
case CLOCK_REALTIME:
case CLOCK_MONOTONIC:
clk_serv_id = clk_id == CLOCK_REALTIME ? CALENDAR_CLOCK : SYSTEM_CLOCK;
if (KERN_SUCCESS == (ret = host_get_clock_service(mach_host_self(), clk_serv_id, &clk))) {
if (KERN_SUCCESS == (ret = clock_get_time(clk, &tm))) {
tp->tv_sec = tm.tv_sec;
tp->tv_nsec = tm.tv_nsec;
retval = 0;
}
clk_serv = (clk_id == CLOCK_REALTIME) ? belle_sip_calandar_clk : belle_sip_system_clk;
if (KERN_SUCCESS == (ret = clock_get_time(clk_serv, &tm))) {
tp->tv_sec = tm.tv_sec;
tp->tv_nsec = tm.tv_nsec;
retval = 0;
}
if (KERN_SUCCESS != ret) {
errno = EINVAL;
retval = -1;
}
break;
break;
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_THREAD_CPUTIME_ID:
start = mach_absolute_time();
......@@ -112,15 +119,15 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp) {
sched_yield();
}
end = mach_absolute_time();
delta = end - start;
delta = end - start;
if (0 == __clock_gettime_inf.denom) {
mach_timebase_info(&__clock_gettime_inf);
}
nano = delta * __clock_gettime_inf.numer / __clock_gettime_inf.denom;
tp->tv_sec = nano * 1e-9;
tp->tv_sec = nano * 1e-9;
tp->tv_nsec = nano - (tp->tv_sec * 1e9);
retval = 0;
break;
break;
default:
errno = EINVAL;
retval = -1;
......
......@@ -298,7 +298,8 @@ int belle_http_channel_is_busy(belle_sip_channel_t *obj) {
if (obj->incoming_messages != NULL || obj->outgoing_messages != NULL) {
return 1;
}
for (it = obj->listeners; it != NULL; it = it->next) {
/*fixme, a litle bit intrusive*/
for (it = obj->full_listeners; it != NULL; it = it->next) {
if (BELLE_SIP_IS_INSTANCE_OF(it->data, belle_http_channel_context_t)) {
belle_http_channel_context_t *obj = it->data;
return obj->pending_requests != NULL;
......
......@@ -118,7 +118,7 @@ const void* belle_sip_thread_getspecific(belle_sip_thread_key_t key);
int belle_sip_thread_key_delete(belle_sip_thread_key_t key);
static BELLESIP_INLINE void close_socket(belle_sip_socket_t s){
static BELLESIP_INLINE void belle_sip_close_socket(belle_sip_socket_t s){
closesocket(s);
}
......@@ -192,7 +192,7 @@ typedef pthread_key_t belle_sip_thread_key_t;
#define belle_sip_thread_getspecific(key) pthread_getspecific(key)
#define belle_sip_thread_key_delete(key) pthread_key_delete(key)
static BELLESIP_INLINE void close_socket(belle_sip_socket_t s){
static BELLESIP_INLINE void belle_sip_close_socket(belle_sip_socket_t s){
close(s);
}
......
......@@ -81,7 +81,7 @@ void stream_channel_close(belle_sip_stream_channel_t *obj){
obj->write_stream=NULL;
}
#endif
close_socket(sock);
belle_sip_close_socket(sock);
}
}
......@@ -138,7 +138,7 @@ int stream_channel_connect(belle_sip_stream_channel_t *obj, const struct addrinf
err = connect(sock,ai->ai_addr,ai->ai_addrlen);
if (err != 0 && get_socket_error()!=BELLESIP_EINPROGRESS && get_socket_error()!=BELLESIP_EWOULDBLOCK) {
belle_sip_error("stream connect failed %s",belle_sip_get_socket_error_string());
close_socket(sock);
belle_sip_close_socket(sock);
return -1;
}
belle_sip_channel_set_socket((belle_sip_channel_t*)obj,sock,(belle_sip_source_func_t)stream_channel_process_data);
......
......@@ -23,7 +23,7 @@ static int on_new_connection(void *userdata, unsigned int events);
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);
belle_sip_close_socket(lp->server_sock);
lp->server_sock=-1;
}
if (lp->source){
......@@ -102,7 +102,7 @@ static belle_sip_socket_t create_server_socket(const char *addr, int * port, int
err=bind(sock,res->ai_addr,res->ai_addrlen);
if (err==-1){
belle_sip_error("TCP bind() failed for %s port %i: %s",addr,*port,belle_sip_get_socket_error_string());
close_socket(sock);