Commit c7a6cb09 authored by Simon Morlat's avatar Simon Morlat

fix vtables

linphone_core_remove_listener() can safely be called from within a callback.
don't destroy the vtable in linphone_core_destroy(), similar to what is done with linphone_core_remove_listener().
parent f7916564
......@@ -91,6 +91,7 @@ set(SOURCE_FILES
xml2lpc.c
xml2lpc.h
xml.c
vtables.c
)
if(ENABLE_TUNNEL)
list(APPEND SOURCE_FILES
......
......@@ -81,6 +81,7 @@ liblinphone_la_SOURCES=\
sipsetup.c sipsetup.h \
xml2lpc.c \
xml.c \
vtables.c \
$(GITVERSION_FILE)
if BUILD_UPNP
......
/*
linphone
Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
Copyright (C) 2010 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
......@@ -1618,7 +1619,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
memcpy(local_vtable,vtable,sizeof(LinphoneCoreVTable));
lc->vtables=ms_list_append(lc->vtables,local_vtable);
_linphone_core_add_listener(lc, local_vtable, TRUE);
linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");
ortp_init();
......@@ -6348,7 +6349,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
ms_exit();
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
linphone_core_deactivate_log_serialization_if_needed();
ms_list_free_with_data(lc->vtables,(void (*)(void *))linphone_core_v_table_destroy);
ms_list_free_with_data(lc->vtable_refs,(void (*)(void *))v_table_reference_destroy);
}
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime){
......@@ -7130,144 +7131,6 @@ int linphone_payload_type_get_channels(const LinphonePayloadType *pt) {
return pt->channels;
}
LinphoneCoreVTable *linphone_core_v_table_new() {
return ms_new0(LinphoneCoreVTable,1);
}
void linphone_core_v_table_set_user_data(LinphoneCoreVTable *table, void *data) {
table->user_data = data;
}
void* linphone_core_v_table_get_user_data(LinphoneCoreVTable *table) {
return table->user_data;
}
void linphone_core_v_table_destroy(LinphoneCoreVTable* table) {
ms_free(table);
}
LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) {
return lc->current_vtable;
}
#define NOTIFY_IF_EXIST(function_name) \
MSList* iterator; \
ms_message ("Linphone core [%p] notifying [%s]",lc,#function_name);\
for (iterator=lc->vtables; iterator!=NULL; iterator=iterator->next) \
if ((lc->current_vtable=((LinphoneCoreVTable*)(iterator->data)))->function_name)\
((LinphoneCoreVTable*)(iterator->data))->function_name
void linphone_core_notify_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
NOTIFY_IF_EXIST(global_state_changed)(lc,gstate,message);
}
void linphone_core_notify_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message){
NOTIFY_IF_EXIST(call_state_changed)(lc,call,cstate,message);
}
void linphone_core_notify_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token) {
NOTIFY_IF_EXIST(call_encryption_changed)(lc,call,on,authentication_token);
}
void linphone_core_notify_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
NOTIFY_IF_EXIST(registration_state_changed)(lc,cfg,cstate,message);
}
void linphone_core_notify_show_interface(LinphoneCore *lc){
NOTIFY_IF_EXIST(show)(lc);
}
void linphone_core_notify_display_status(LinphoneCore *lc, const char *message) {
NOTIFY_IF_EXIST(display_status)(lc,message);
}
void linphone_core_notify_display_message(LinphoneCore *lc, const char *message){
NOTIFY_IF_EXIST(display_message)(lc,message);
}
void linphone_core_notify_display_warning(LinphoneCore *lc, const char *message){
NOTIFY_IF_EXIST(display_warning)(lc,message);
}
void linphone_core_notify_display_url(LinphoneCore *lc, const char *message, const char *url){
NOTIFY_IF_EXIST(display_url)(lc,message,url);
}
void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf){
NOTIFY_IF_EXIST(notify_presence_received)(lc,lf);
}
void linphone_core_notify_new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
NOTIFY_IF_EXIST(new_subscription_requested)(lc,lf,url);
}
void linphone_core_notify_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain){
NOTIFY_IF_EXIST(auth_info_requested)(lc,realm,username,domain);
}
void linphone_core_notify_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){
NOTIFY_IF_EXIST(call_log_updated)(lc,newcl);
}
void linphone_core_notify_text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message){
NOTIFY_IF_EXIST(text_received)(lc,room,from,message);
}
void linphone_core_notify_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message){
NOTIFY_IF_EXIST(message_received)(lc,room,message);
}
void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) {
NOTIFY_IF_EXIST(file_transfer_recv)(lc,message,content,buff,size);
}
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) {
NOTIFY_IF_EXIST(file_transfer_send)(lc,message,content,buff,size);
}
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) {
NOTIFY_IF_EXIST(file_transfer_progress_indication)(lc,message,content,offset,total);
}
void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
NOTIFY_IF_EXIST(is_composing_received)(lc,room);
}
void linphone_core_notify_dtmf_received(LinphoneCore* lc, LinphoneCall *call, int dtmf) {
NOTIFY_IF_EXIST(dtmf_received)(lc,call,dtmf);
}
bool_t linphone_core_dtmf_received_has_listener(const LinphoneCore* lc) {
MSList* iterator;
for (iterator=lc->vtables; iterator!=NULL; iterator=iterator->next)
if (((LinphoneCoreVTable*)(iterator->data))->dtmf_received)
return TRUE;
return FALSE;
}
void linphone_core_notify_refer_received(LinphoneCore *lc, const char *refer_to) {
NOTIFY_IF_EXIST(refer_received)(lc,refer_to);
}
void linphone_core_notify_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf) {
NOTIFY_IF_EXIST(buddy_info_updated)(lc,lf);
}
void linphone_core_notify_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state) {
NOTIFY_IF_EXIST(transfer_state_changed)(lc,transfered,new_call_state);
}
void linphone_core_notify_call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats) {
NOTIFY_IF_EXIST(call_stats_updated)(lc,call,stats);
}
void linphone_core_notify_info_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg) {
NOTIFY_IF_EXIST(info_received)(lc,call,msg);
}
void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) {
NOTIFY_IF_EXIST(configuring_status)(lc,status,message);
}
void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable) {
NOTIFY_IF_EXIST(network_reachable)(lc,reachable);
}
void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) {
NOTIFY_IF_EXIST(notify_received)(lc,lev,notified_event,body);
}
void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
NOTIFY_IF_EXIST(subscription_state_changed)(lc,lev,state);
}
void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state) {
NOTIFY_IF_EXIST(publish_state_changed)(lc,lev,state);
}
void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) {
NOTIFY_IF_EXIST(log_collection_upload_state_changed)(lc, state, info);
}
void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t offset, size_t total) {
NOTIFY_IF_EXIST(log_collection_upload_progress_indication)(lc, offset, total);
}
void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable) {
ms_message("Vtable [%p] registered on core [%p]",lc,vtable);
lc->vtables=ms_list_append(lc->vtables,vtable);
}
void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *vtable) {
ms_message("Vtable [%p] unregistered on core [%p]",lc,vtable);
lc->vtables=ms_list_remove(lc->vtables,(void*)vtable);
}
int linphone_core_set_audio_multicast_addr(LinphoneCore *lc, const char* ip) {
char* new_value;
if (ip && !ms_is_multicast(ip)) {
......@@ -7296,7 +7159,6 @@ const char* linphone_core_get_audio_multicast_addr(const LinphoneCore *lc) {
return lc->rtp_conf.audio_multicast_addr;
}
const char* linphone_core_get_video_multicast_addr(const LinphoneCore *lc){
return lc->rtp_conf.video_multicast_addr;
}
......
......@@ -1890,7 +1890,7 @@ typedef struct _LinphoneCoreVTable{
LinphoneCoreNetworkReachableCb network_reachable; /**< Callback to report IP network status (I.E up/down )*/
LinphoneCoreLogCollectionUploadStateChangedCb log_collection_upload_state_changed; /**< Callback to upload collected logs */
LinphoneCoreLogCollectionUploadProgressIndicationCb log_collection_upload_progress_indication; /**< Callback to indicate log collection upload progress */
void *user_data;
void *user_data; /**<User data associated with the above callbacks */
} LinphoneCoreVTable;
/**
......
......@@ -1193,8 +1193,9 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeListener(JNIEnv* e
MSList* iterator;
LinphoneCore *core = (LinphoneCore*)lc;
//jobject listener = env->NewGlobalRef(jlistener);
for (iterator = core->vtables; iterator != NULL; ) {
LinphoneCoreVTable *vTable = (LinphoneCoreVTable*)(iterator->data);
for (iterator = core->vtable_refs; iterator != NULL; ) {
VTableReference *ref=(VTableReference*)(iterator->data);
LinphoneCoreVTable *vTable = ref->valid ? ref->vtable : NULL;
iterator = iterator->next; //Because linphone_core_remove_listener may change the list
if (vTable) {
LinphoneCoreData *data = (LinphoneCoreData*) linphone_core_v_table_get_user_data(vTable);
......
......@@ -717,7 +717,7 @@ typedef struct _LinphoneConference LinphoneConference;
struct _LinphoneCore
{
MSList* vtables;
MSList* vtable_refs;
Sal *sal;
LinphoneGlobalState state;
struct _LpConfig *config;
......@@ -767,6 +767,8 @@ struct _LinphoneCore
char* zrtp_secrets_cache;
char* user_certificates_path;
LinphoneVideoPolicy video_policy;
time_t network_last_check;
bool_t use_files;
bool_t apply_nat_settings;
bool_t initial_subscribes_sent;
......@@ -776,13 +778,11 @@ struct _LinphoneCore
bool_t auto_net_state_mon;
bool_t network_reachable;
bool_t network_reachable_to_be_notified; /*set to true when state must be notified in next iterate*/
bool_t use_preview_window;
time_t network_last_check;
bool_t network_last_status;
bool_t ringstream_autorelease;
bool_t pad[2];
bool_t vtables_running;
char localip[LINPHONE_IPADDR_SIZE];
int device_rotation;
int max_calls;
......@@ -1121,6 +1121,18 @@ void linphone_core_multicast_lock_acquire(LinphoneCore *lc);
void linphone_core_multicast_lock_release(LinphoneCore *lc);
#endif
struct _VTableReference{
LinphoneCoreVTable *vtable;
bool_t valid;
bool_t autorelease;
};
typedef struct _VTableReference VTableReference;
void v_table_reference_destroy(VTableReference *ref);
void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, bool_t autorelease);
#ifdef __cplusplus
}
#endif
......
oRTP @ 9f6a7f42
Subproject commit f3a7c4d92dd9e18ff63c744611aac7f1adb12aca
Subproject commit 9f6a7f42e0ee7ce89452ee9f7be8b97b891370ed
......@@ -2673,9 +2673,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user
linphone_core_set_user_agent(marie->lc,user_agent,NULL);
}
if (!enable_auth_req_cb) {
((LinphoneCoreVTable*)(marie->lc->vtables->data))->auth_info_requested=NULL;
((VTableReference*)(marie->lc->vtable_refs->data))->vtable->auth_info_requested=NULL;
linphone_core_add_auth_info(marie->lc,wrong_auth_info);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment