forked from mirrors/linphone-iphone
-fix many memory leak
-unsubscribe in linphone_core_uninit
This commit is contained in:
parent
05adaae843
commit
966c7caa2d
11 changed files with 69 additions and 32 deletions
|
|
@ -747,6 +747,7 @@ static void set_tls_properties(Sal *ctx){
|
|||
belle_tls_crypto_config_set_verify_exceptions(crypto_config, verify_exceptions);
|
||||
if (ctx->root_ca != NULL) belle_tls_crypto_config_set_root_ca(crypto_config, ctx->root_ca);
|
||||
belle_sip_tls_listening_point_set_crypto_config(tlp, crypto_config);
|
||||
belle_sip_object_unref(crypto_config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,6 +195,18 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
|
|||
|
||||
static belle_sip_listener_callbacks_t op_subscribe_callbacks={ 0 };
|
||||
|
||||
/*Invoke when sal_op_release is called by upper layer*/
|
||||
static void sal_op_release_cb(struct SalOpBase* op_base) {
|
||||
SalOp *op =(SalOp*)op_base;
|
||||
if(op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_object_unref(op->refresher);
|
||||
op->refresher=NULL;
|
||||
set_or_update_dialog(op,NULL); /*only if we have refresher. else dialog terminated event will remove association*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sal_op_subscribe_fill_cbs(SalOp*op) {
|
||||
if (op_subscribe_callbacks.process_io_error==NULL){
|
||||
op_subscribe_callbacks.process_io_error=subscribe_process_io_error;
|
||||
|
|
@ -206,6 +218,7 @@ void sal_op_subscribe_fill_cbs(SalOp*op) {
|
|||
}
|
||||
op->callbacks=&op_subscribe_callbacks;
|
||||
op->type=SalOpSubscribe;
|
||||
op->base.release_cb=sal_op_release_cb;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ void sal_op_release(SalOp *op){
|
|||
if (op->state!=SalOpStateTerminating)
|
||||
op->state=SalOpStateTerminated;
|
||||
sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn't not mean freeing op. Make sure back pointer will not be used later*/
|
||||
if (op->base.release_cb)
|
||||
op->base.release_cb(&op->base);
|
||||
if (op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,24 +52,13 @@ static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_e
|
|||
|
||||
static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
|
||||
SalOp* op= (SalOp*)ctx;
|
||||
if (op->dialog) {
|
||||
if (belle_sip_dialog_is_server(op->dialog)){
|
||||
if (op->dialog && belle_sip_dialog_is_server(op->dialog)) {
|
||||
ms_message("Incoming subscribtion from [%s] terminated",sal_op_get_from(op));
|
||||
if (!op->op_released){
|
||||
op->base.root->callbacks.subscribe_presence_closed(op, sal_op_get_from(op));
|
||||
}
|
||||
set_or_update_dialog(op, NULL);
|
||||
}else{
|
||||
if (belle_sip_dialog_terminated_event_is_expired(event)){
|
||||
ms_warning("Outgoing presence subscription expired.");
|
||||
if (op->refresher){
|
||||
/*send a new SUBSCRIBE, that will attempt to establish a new dialog*/
|
||||
sal_subscribe_presence(op,NULL,NULL,-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}/* else client dialog is managed by refresher*/
|
||||
}
|
||||
|
||||
static void presence_refresher_listener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase){
|
||||
|
|
@ -144,13 +133,6 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
|
|||
}
|
||||
break;
|
||||
}
|
||||
case BELLE_SIP_DIALOG_TERMINATED:
|
||||
if (op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_object_unref(op->refresher);
|
||||
op->refresher=NULL;
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
ms_error("presence op [%p] receive answer [%i] not implemented",op,code);
|
||||
}
|
||||
|
|
@ -297,6 +279,17 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
|
|||
|
||||
static belle_sip_listener_callbacks_t op_presence_callbacks={0};
|
||||
|
||||
/*Invoke when sal_op_release is called by upper layer*/
|
||||
static void sal_op_release_cb(struct SalOpBase* op_base) {
|
||||
SalOp *op =(SalOp*)op_base;
|
||||
if(op->refresher) {
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
belle_sip_object_unref(op->refresher);
|
||||
op->refresher=NULL;
|
||||
set_or_update_dialog(op,NULL); /*only if we have refresher. else dialog terminated event will remove association*/
|
||||
}
|
||||
|
||||
}
|
||||
void sal_op_presence_fill_cbs(SalOp*op) {
|
||||
if (op_presence_callbacks.process_request_event==NULL){
|
||||
op_presence_callbacks.process_io_error=presence_process_io_error;
|
||||
|
|
@ -308,6 +301,7 @@ void sal_op_presence_fill_cbs(SalOp*op) {
|
|||
}
|
||||
op->callbacks=&op_presence_callbacks;
|
||||
op->type=SalOpPresence;
|
||||
op->base.release_cb=sal_op_release_cb;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -380,6 +374,7 @@ int sal_notify_presence(SalOp *op, SalPresenceModel *presence){
|
|||
|
||||
int sal_notify_presence_close(SalOp *op){
|
||||
belle_sip_request_t* notify=NULL;
|
||||
int status;
|
||||
if (sal_op_check_dialog_state(op)) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -389,7 +384,9 @@ int sal_notify_presence_close(SalOp *op){
|
|||
sal_add_presence_info(op,BELLE_SIP_MESSAGE(notify),NULL); /*FIXME, what about expires ??*/
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
|
||||
,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,-1)));
|
||||
return sal_op_send_request(op,notify);
|
||||
status = sal_op_send_request(op,notify);
|
||||
set_or_update_dialog(op,NULL); /*because we may be chalanged for the notify, so we must release dialog right now*/
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1135,6 +1135,7 @@ static void convert_presence_to_xml_requested(SalOp *op, SalPresenceModel *prese
|
|||
if(linphone_presence_model_get_presentity((LinphonePresenceModel*)presence) == NULL) {
|
||||
LinphoneAddress * presentity = linphone_address_new(contact);
|
||||
linphone_presence_model_set_presentity((LinphonePresenceModel*)presence, presentity);
|
||||
linphone_address_unref(presentity);
|
||||
}
|
||||
*content = linphone_presence_model_to_xml((LinphonePresenceModel*)presence);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -599,7 +599,9 @@ LinphoneFriend * linphone_friend_list_find_friend_by_out_subscribe(const Linphon
|
|||
|
||||
void linphone_friend_list_close_subscriptions(LinphoneFriendList *list) {
|
||||
/* FIXME we should wait until subscription to complete. */
|
||||
if (list->friends)
|
||||
if (list->event) {
|
||||
linphone_event_terminate(list->event);
|
||||
} else if (list->friends)
|
||||
ms_list_for_each(list->friends, (void (*)(void *))linphone_friend_close_subscriptions);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6493,6 +6493,8 @@ LpConfig * linphone_core_create_lp_config(LinphoneCore *lc, const char *filename
|
|||
static void linphone_core_uninit(LinphoneCore *lc)
|
||||
{
|
||||
MSList *elem = NULL;
|
||||
int i=0;
|
||||
bool_t wait_until_unsubscribe = FALSE;
|
||||
linphone_task_list_free(&lc->hooks);
|
||||
lc->video_conf.show_local = FALSE;
|
||||
|
||||
|
|
@ -6506,6 +6508,13 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)elem->data;
|
||||
linphone_friend_list_close_subscriptions(list);
|
||||
if (list->event)
|
||||
wait_until_unsubscribe = TRUE;
|
||||
}
|
||||
/*give a chance to unsubscribe, might be optimized*/
|
||||
for (i=0; wait_until_unsubscribe && i<20; i++) {
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ typedef struct _LinphoneFriend LinphoneFriend;
|
|||
* @return a new empty #LinphoneFriend
|
||||
* @deprecated use #linphone_core_create_friend instead
|
||||
*/
|
||||
LINPHONE_PUBLIC MS2_DEPRECATED LinphoneFriend * linphone_friend_new(void); /*fix me me replace MS2_DEPRECATED by LINPHONE_DEPRECATED*/
|
||||
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneFriend * linphone_friend_new(void);
|
||||
|
||||
/**
|
||||
* Contructor same as linphone_friend_new() + linphone_friend_set_address()
|
||||
|
|
@ -129,7 +129,7 @@ LINPHONE_PUBLIC MS2_DEPRECATED LinphoneFriend * linphone_friend_new(void); /*fix
|
|||
* @return a new #LinphoneFriend with \link linphone_friend_get_address() address initialized \endlink
|
||||
* @deprecated use #linphone_core_create_friend_with_address instead
|
||||
*/
|
||||
LINPHONE_PUBLIC MS2_DEPRECATED LinphoneFriend *linphone_friend_new_with_address(const char *addr); /*fix me me replace MS2_DEPRECATED by LINPHONE_DEPRECATED*/
|
||||
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneFriend *linphone_friend_new_with_address(const char *addr);
|
||||
|
||||
/**
|
||||
* Contructor same as linphone_friend_new() + linphone_friend_set_address()
|
||||
|
|
|
|||
|
|
@ -330,7 +330,9 @@ bool_t sal_media_description_has_srtp(const SalMediaDescription *md);
|
|||
bool_t sal_media_description_has_dtls(const SalMediaDescription *md);
|
||||
int sal_media_description_get_nb_active_streams(const SalMediaDescription *md);
|
||||
|
||||
|
||||
struct SalOpBase;
|
||||
typedef void (*SalOpReleaseCb)(struct SalOpBase *op);
|
||||
|
||||
/*this structure must be at the first byte of the SalOp structure defined by implementors*/
|
||||
typedef struct SalOpBase{
|
||||
Sal *root;
|
||||
|
|
@ -355,6 +357,7 @@ typedef struct SalOpBase{
|
|||
SalCustomHeader *sent_custom_headers;
|
||||
SalCustomHeader *recv_custom_headers;
|
||||
char* entity_tag; /*as defined by rfc3903 (I.E publih)*/
|
||||
SalOpReleaseCb release_cb;
|
||||
} SalOpBase;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -360,10 +360,10 @@ static void publish_without_expires(void){
|
|||
|
||||
test_t event_tests[] = {
|
||||
TEST_ONE_TAG("Subscribe declined", subscribe_test_declined, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber, "presence"),
|
||||
TEST_ONE_TAG("Subscribe with custom headers", subscribe_test_with_custom_header, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Subscribe refreshed", subscribe_test_refreshed, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Subscribe manually refreshed", subscribe_test_manually_refreshed, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Subscribe refreshed", subscribe_test_refreshed, "presence"),
|
||||
TEST_ONE_TAG("Subscribe manually refreshed", subscribe_test_manually_refreshed, "presence"),
|
||||
TEST_ONE_TAG("Subscribe terminated by notifier", subscribe_test_terminated_by_notifier, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Publish", publish_test, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Publish without expires", publish_without_expires, "LeaksMemory"),
|
||||
|
|
|
|||
|
|
@ -709,7 +709,6 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
const char *marie_identity;
|
||||
const char *pauline_identity;
|
||||
MSList* lcs = NULL;
|
||||
int dummy = 0;
|
||||
|
||||
laure_identity = get_identity(laure);
|
||||
marie_identity = get_identity(marie);
|
||||
|
|
@ -817,13 +816,23 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
enable_publish(marie, FALSE);
|
||||
enable_publish(pauline, FALSE);
|
||||
|
||||
wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the presence notifications. TODO: Wait for the correct number of PresenceReceived events. */
|
||||
|
||||
reset_counters(&pauline->stat);
|
||||
reset_counters(&laure->stat);
|
||||
reset_counters(&marie->stat);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphonePresenceActivityOffline, 1, 2000));
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphonePresenceActivityOffline, 2, 2000));
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphonePresenceActivityOffline, 1, 2000));
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
|
||||
|
|
@ -1023,7 +1032,7 @@ static void simple_subscribe_with_friend_from_rc(void) {
|
|||
|
||||
|
||||
test_t presence_tests[] = {
|
||||
TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"LeaksMemory"),
|
||||
TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
|
||||
TEST_ONE_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc,"LeaksMemory"),
|
||||
TEST_ONE_TAG("Simple Publish", simple_publish, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Simple Publish with expires", publish_with_expires, "LeaksMemory"),
|
||||
|
|
@ -1033,7 +1042,7 @@ test_t presence_tests[] = {
|
|||
TEST_NO_TAG("App managed presence failure", subscribe_failure_handle_by_app),
|
||||
TEST_NO_TAG("Presence SUBSCRIBE forked", subscribe_presence_forked),
|
||||
TEST_NO_TAG("Presence SUBSCRIBE expired", subscribe_presence_expired),
|
||||
TEST_ONE_TAG("Subscriber no longer reachable using server",subscriber_no_longer_reachable, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Subscriber no longer reachable using server",subscriber_no_longer_reachable, "presence"),
|
||||
TEST_ONE_TAG("Subscribe with late publish", test_subscribe_notify_publish, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish, "LeaksMemory"),
|
||||
TEST_ONE_TAG("Presence list", test_presence_list, "LeaksMemory"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue