From d3e3740a64b1f4d2d3b0313b5564216d9d6e4862 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 6 Feb 2016 11:51:06 +0100 Subject: [PATCH] fix crashes around presence and publish. Documentation was not consistent with actual code was doing. LinphoneEvent becomes a true belle_sip_object_t, which now evidences memory leaks. update ms2 --- coreapi/event.c | 39 +++++++++++++++++++++++++++++++++------ coreapi/event.h | 6 ++---- coreapi/friendlist.c | 1 + coreapi/private.h | 6 ++++-- coreapi/proxy.c | 1 + mediastreamer2 | 2 +- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/coreapi/event.c b/coreapi/event.c index 07e373b73..8f00111d8 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -20,6 +20,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "private.h" #include "lpconfig.h" +const char * linphone_subscription_dir_to_string(LinphoneSubscriptionDir dir){ + switch(dir){ + case LinphoneSubscriptionIncoming: + return "LinphoneSubscriptionIncoming"; + case LinphoneSubscriptionOutgoing: + return "LinphoneSubscriptionOutgoing"; + case LinphoneSubscriptionInvalidDir: + return "LinphoneSubscriptionInvalidDir"; + } + return "INVALID"; +} LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss){ switch(ss){ @@ -58,11 +69,10 @@ LINPHONE_PUBLIC const char *linphone_publish_state_to_string(LinphonePublishStat } static LinphoneEvent * linphone_event_new_base(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, SalOp *op){ - LinphoneEvent *lev=ms_new0(LinphoneEvent,1); + LinphoneEvent *lev=belle_sip_object_new(LinphoneEvent); lev->lc=lc; lev->dir=dir; lev->op=op; - lev->refcnt=1; lev->name=ms_strdup(name); sal_op_set_user_pointer(lev->op,lev); return lev; @@ -343,7 +353,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ LinphoneEvent *linphone_event_ref(LinphoneEvent *lev){ - lev->refcnt++; + belle_sip_object_ref(lev); return lev; } @@ -351,12 +361,10 @@ static void linphone_event_destroy(LinphoneEvent *lev){ if (lev->op) sal_op_release(lev->op); ms_free(lev->name); - ms_free(lev); } void linphone_event_unref(LinphoneEvent *lev){ - lev->refcnt--; - if (lev->refcnt==0) linphone_event_destroy(lev); + belle_sip_object_unref(lev); } LinphoneSubscriptionDir linphone_event_get_subscription_dir(LinphoneEvent *lev){ @@ -391,3 +399,22 @@ LinphoneCore *linphone_event_get_core(const LinphoneEvent *lev){ return lev->lc; } +static belle_sip_error_code _linphone_event_marshall(belle_sip_object_t *obj, char* buff, size_t buff_size, size_t *offset) { + LinphoneEvent *ev = (LinphoneEvent*)obj; + belle_sip_error_code err = BELLE_SIP_OK; + + err = belle_sip_snprintf(buff, buff_size, offset, "%s of %s", ev->dir == LinphoneSubscriptionIncoming ? + "Incoming Subscribe" : (ev->dir == LinphoneSubscriptionOutgoing ? "Outgoing subscribe" : "Publish"), ev->name); + + return err; +} + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneEvent); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneEvent, belle_sip_object_t, + (belle_sip_object_destroy_t) linphone_event_destroy, + NULL, // clone + _linphone_event_marshall, + FALSE +); + diff --git a/coreapi/event.h b/coreapi/event.h index b9033f8c7..d84d6d180 100644 --- a/coreapi/event.h +++ b/coreapi/event.h @@ -278,10 +278,8 @@ LINPHONE_PUBLIC const char *linphone_event_get_custom_header(LinphoneEvent *ev, /** * Terminate an incoming or outgoing subscription that was previously acccepted, or a previous publication. - * This function does not unref the object. The core will unref() if it does not need this object anymore. - * - * For subscribed event, when the subscription is terminated normally or because of an error, the core will unref. - * For published events, no unref is performed. This is because it is allowed to re-publish an expired publish, as well as retry it in case of error. + * The LinphoneEvent shall not be used anymore after this operation, unless the application explicitely took a reference on the object with + * linphone_event_ref(). **/ LINPHONE_PUBLIC void linphone_event_terminate(LinphoneEvent *lev); diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index fd0841782..aba3546ff 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -408,6 +408,7 @@ void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, Linphon linphone_event_unref(list->event); } list->event = linphone_core_create_subscribe(list->lc, address, "presence", expires); + linphone_event_ref(list->event); linphone_event_set_internal(list->event, TRUE); linphone_event_add_custom_header(list->event, "Require", "recipient-list-subscribe"); linphone_event_add_custom_header(list->event, "Supported", "eventlist"); diff --git a/coreapi/private.h b/coreapi/private.h index acea2859a..a041c8126 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -982,6 +982,7 @@ struct _LinphoneCore struct _LinphoneEvent{ + belle_sip_object_t base; LinphoneSubscriptionDir dir; LinphoneCore *lc; SalOp *op; @@ -989,7 +990,6 @@ struct _LinphoneEvent{ LinphoneSubscriptionState subscription_state; LinphonePublishState publish_state; void *userdata; - int refcnt; char *name; int expires; bool_t terminating; @@ -997,6 +997,7 @@ struct _LinphoneEvent{ bool_t internal; }; +BELLE_SIP_DECLARE_VPTR(LinphoneEvent); LinphoneTunnel *linphone_core_tunnel_new(LinphoneCore *lc); void linphone_tunnel_destroy(LinphoneTunnel *tunnel); @@ -1335,7 +1336,8 @@ BELLE_SIP_TYPE_ID(LinphoneFriendList), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequestCbs), BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession), -BELLE_SIP_TYPE_ID(LinphoneTunnelConfig) +BELLE_SIP_TYPE_ID(LinphoneTunnelConfig), +BELLE_SIP_TYPE_ID(LinphoneEvent) BELLE_SIP_DECLARE_TYPES_END diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 90c5def90..08e56194d 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -1093,6 +1093,7 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese , linphone_proxy_config_get_identity_address(proxy) , "presence" , linphone_proxy_config_get_publish_expires(proxy)); + linphone_event_ref(proxy->long_term_event); } proxy->long_term_event->internal = TRUE; diff --git a/mediastreamer2 b/mediastreamer2 index 97ee2fdb8..b77a99786 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 97ee2fdb8365480d95f366529db41f5291bd1fbf +Subproject commit b77a997867d77ec22a4a51dcd415c294298da8f6