Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
3e7baa8a
Commit
3e7baa8a
authored
Jan 20, 2020
by
Paul Cartier
Browse files
Asynchronous core stop
parent
f1c08b5e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
240 additions
and
1 deletion
+240
-1
coreapi/linphonecore.c
coreapi/linphonecore.c
+128
-0
coreapi/private_structs.h
coreapi/private_structs.h
+2
-1
include/linphone/core.h
include/linphone/core.h
+11
-0
src/core/core-p.h
src/core/core-p.h
+3
-0
src/core/core.cpp
src/core/core.cpp
+47
-0
tester/call_single_tester.c
tester/call_single_tester.c
+20
-0
tester/liblinphone_tester.h
tester/liblinphone_tester.h
+2
-0
tester/tester.c
tester/tester.c
+27
-0
No files found.
coreapi/linphonecore.c
View file @
3e7baa8a
...
...
@@ -147,6 +147,7 @@ static void set_media_network_reachable(LinphoneCore* lc,bool_t isReachable);
static
void
linphone_core_run_hooks
(
LinphoneCore
*
lc
);
static
void
linphone_core_zrtp_cache_close
(
LinphoneCore
*
lc
);
void
linphone_core_zrtp_cache_db_init
(
LinphoneCore
*
lc
,
const
char
*
fileName
);
static
void
_linphone_core_stop_async_end
(
LinphoneCore
*
lc
);
#include "enum.h"
#include "contact_providers_priv.h"
...
...
@@ -3625,6 +3626,12 @@ void linphone_core_iterate(LinphoneCore *lc){
if
(
liblinphone_serialize_logs
==
TRUE
)
{
ortp_logv_flush
();
}
if
(
lc
->
state
==
LinphoneGlobalShutdown
&&
lc
->
async_stop
)
{
if
(
L_GET_PRIVATE_FROM_C_OBJECT
(
lc
)
->
asyncStopDone
())
{
_linphone_core_stop_async_end
(
lc
);
}
}
}
LinphoneAddress
*
linphone_core_interpret_url
(
LinphoneCore
*
lc
,
const
char
*
url
){
...
...
@@ -6329,12 +6336,129 @@ LinphoneXmlRpcSession * linphone_core_create_xml_rpc_session(LinphoneCore *lc, c
return
linphone_xml_rpc_session_new
(
lc
,
url
);
}
/**
* First part of the async Core stop:
* Called by linphone_core_stop_async() to begin the async stop process and change the state to "Shutdown"
*/
static
void
_linphone_core_stop_async_start
(
LinphoneCore
*
lc
)
{
linphone_task_list_free
(
&
lc
->
hooks
);
lc
->
video_conf
.
show_local
=
FALSE
;
lc
->
async_stop
=
TRUE
;
L_GET_PRIVATE_FROM_C_OBJECT
(
lc
)
->
shutdown
();
#ifdef VIDEO_ENABLED
if
(
lc
->
previewstream
!=
NULL
){
video_preview_stop
(
lc
->
previewstream
);
lc
->
previewstream
=
NULL
;
}
#endif
lc
->
msevq
=
NULL
;
linphone_core_stop_ringing
(
lc
);
linphone_core_set_state
(
lc
,
LinphoneGlobalShutdown
,
"Shutdown"
);
}
/**
* Second part of the async Core stop:
* After we made sure all asynchronous tasks are finished, this function is called to clean the objects
* and change the state to "Off"
*/
static
void
_linphone_core_stop_async_end
(
LinphoneCore
*
lc
)
{
L_GET_PRIVATE_FROM_C_OBJECT
(
lc
)
->
stop
();
lc
->
chat_rooms
=
bctbx_list_free_with_data
(
lc
->
chat_rooms
,
(
bctbx_list_free_func
)
linphone_chat_room_unref
);
getPlatformHelpers
(
lc
)
->
onLinphoneCoreStop
();
/* save all config */
friends_config_uninit
(
lc
);
sip_config_uninit
(
lc
);
net_config_uninit
(
lc
);
rtp_config_uninit
(
lc
);
sound_config_uninit
(
lc
);
video_config_uninit
(
lc
);
codecs_config_uninit
(
lc
);
sip_setup_unregister_all
();
if
(
lp_config_needs_commit
(
lc
->
config
))
lp_config_sync
(
lc
->
config
);
bctbx_list_for_each
(
lc
->
call_logs
,(
void
(
*
)(
void
*
))
linphone_call_log_unref
);
lc
->
call_logs
=
bctbx_list_free
(
lc
->
call_logs
);
if
(
lc
->
zrtp_secrets_cache
!=
NULL
)
{
ms_free
(
lc
->
zrtp_secrets_cache
);
lc
->
zrtp_secrets_cache
=
NULL
;
}
if
(
lc
->
user_certificates_path
!=
NULL
)
{
ms_free
(
lc
->
user_certificates_path
);
lc
->
user_certificates_path
=
NULL
;
}
if
(
lc
->
play_file
!=
NULL
){
ms_free
(
lc
->
play_file
);
lc
->
play_file
=
NULL
;
}
if
(
lc
->
rec_file
!=
NULL
){
ms_free
(
lc
->
rec_file
);
lc
->
rec_file
=
NULL
;
}
if
(
lc
->
logs_db_file
)
{
ms_free
(
lc
->
logs_db_file
);
lc
->
logs_db_file
=
NULL
;
}
if
(
lc
->
friends_db_file
)
{
ms_free
(
lc
->
friends_db_file
);
lc
->
friends_db_file
=
NULL
;
}
if
(
lc
->
tls_key
){
ms_free
(
lc
->
tls_key
);
lc
->
tls_key
=
NULL
;
}
if
(
lc
->
tls_cert
){
ms_free
(
lc
->
tls_cert
);
lc
->
tls_cert
=
NULL
;
}
if
(
lc
->
ringtoneplayer
)
{
linphone_ringtoneplayer_destroy
(
lc
->
ringtoneplayer
);
lc
->
ringtoneplayer
=
NULL
;
}
if
(
lc
->
im_encryption_engine
)
{
linphone_im_encryption_engine_unref
(
lc
->
im_encryption_engine
);
lc
->
im_encryption_engine
=
NULL
;
}
if
(
lc
->
default_ac_service
)
{
linphone_account_creator_service_unref
(
lc
->
default_ac_service
);
lc
->
default_ac_service
=
NULL
;
}
linphone_core_free_payload_types
(
lc
);
if
(
lc
->
supported_formats
)
ms_free
((
void
*
)
lc
->
supported_formats
);
lc
->
supported_formats
=
NULL
;
linphone_core_call_log_storage_close
(
lc
);
linphone_core_friends_storage_close
(
lc
);
linphone_core_zrtp_cache_close
(
lc
);
ms_bandwidth_controller_destroy
(
lc
->
bw_controller
);
lc
->
bw_controller
=
NULL
;
ms_factory_destroy
(
lc
->
factory
);
lc
->
factory
=
NULL
;
if
(
lc
->
platform_helper
)
delete
getPlatformHelpers
(
lc
);
lc
->
platform_helper
=
NULL
;
linphone_core_set_state
(
lc
,
LinphoneGlobalOff
,
"Off"
);
}
static
void
_linphone_core_stop
(
LinphoneCore
*
lc
)
{
bctbx_list_t
*
elem
=
NULL
;
int
i
=
0
;
bool_t
wait_until_unsubscribe
=
FALSE
;
linphone_task_list_free
(
&
lc
->
hooks
);
lc
->
video_conf
.
show_local
=
FALSE
;
lc
->
async_stop
=
FALSE
;
linphone_core_set_state
(
lc
,
LinphoneGlobalShutdown
,
"Shutdown"
);
...
...
@@ -6448,6 +6572,10 @@ void linphone_core_stop(LinphoneCore *lc) {
_linphone_core_stop
(
lc
);
}
void
linphone_core_stop_async
(
LinphoneCore
*
lc
)
{
_linphone_core_stop_async_start
(
lc
);
}
void
_linphone_core_uninit
(
LinphoneCore
*
lc
)
{
lc
->
is_unreffing
=
TRUE
;
...
...
coreapi/private_structs.h
View file @
3e7baa8a
...
...
@@ -838,7 +838,8 @@ namespace LinphonePrivate {
bctbx_list_t *callsCache; \
bool_t dns_set_by_app; \
int auto_download_incoming_files_max_size; \
bool_t sender_name_hidden_in_forward_message;
bool_t sender_name_hidden_in_forward_message; \
bool_t async_stop;
#define LINPHONE_CORE_STRUCT_FIELDS \
LINPHONE_CORE_STRUCT_BASE_FIELDS \
...
...
include/linphone/core.h
View file @
3e7baa8a
...
...
@@ -1067,6 +1067,17 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_start(LinphoneCore *lc);
*/
LINPHONE_PUBLIC
void
linphone_core_stop
(
LinphoneCore
*
core
);
/**
* Stop asynchronously a #LinphoneCore object after it has been instantiated and started.
* State changes to Shutdown then linphone_core_iterate() must be called to allow the Core to end asynchronous tasks (terminate call, etc.).
* When all tasks are finished, State will change to Off.
* Must be called only if #LinphoneGlobalState is On.
* When #LinphoneGlobalState is Off #LinphoneCore can be started again using linphone_core_start().
* @ingroup initializing
* @param[in] core The #LinphoneCore object to be stopped
*/
LINPHONE_PUBLIC
void
linphone_core_stop_async
(
LinphoneCore
*
core
);
/**
* Increment the reference counter of a #LinphoneCore object.
* @param lc The #LinphoneCore which the ref counter is to be incremented.
...
...
src/core/core-p.h
View file @
3e7baa8a
...
...
@@ -51,6 +51,9 @@ public:
void
registerListener
(
CoreListener
*
listener
);
void
unregisterListener
(
CoreListener
*
listener
);
void
uninit
();
void
shutdown
();
void
stop
();
bool
asyncStopDone
();
void
notifyGlobalStateChanged
(
LinphoneGlobalState
state
);
void
notifyNetworkReachable
(
bool
sipNetworkReachable
,
bool
mediaNetworkReachable
);
...
...
src/core/core.cpp
View file @
3e7baa8a
...
...
@@ -108,6 +108,53 @@ void CorePrivate::unregisterListener (CoreListener *listener) {
listeners
.
remove
(
listener
);
}
bool
CorePrivate
::
asyncStopDone
()
{
L_Q
();
if
(
!
calls
.
empty
())
{
calls
.
front
()
->
terminate
();
return
false
;
}
bctbx_list_t
*
elem
=
NULL
;
for
(
elem
=
q
->
getCCore
()
->
friends_lists
;
elem
!=
NULL
;
elem
=
bctbx_list_next
(
elem
))
{
LinphoneFriendList
*
list
=
(
LinphoneFriendList
*
)
elem
->
data
;
linphone_friend_list_enable_subscriptions
(
list
,
FALSE
);
if
(
list
->
event
)
{
return
false
;
}
}
return
true
;
}
void
CorePrivate
::
shutdown
()
{
if
(
!
calls
.
empty
())
{
calls
.
front
()
->
terminate
();
}
}
void
CorePrivate
::
stop
()
{
L_Q
();
chatRoomsById
.
clear
();
noCreatedClientGroupChatRooms
.
clear
();
listeners
.
clear
();
if
(
q
->
limeX3dhEnabled
())
{
q
->
enableLimeX3dh
(
false
);
}
#ifdef HAVE_ADVANCED_IM
remoteListEventHandler
=
nullptr
;
localListEventHandler
=
nullptr
;
#endif
AddressPrivate
::
clearSipAddressesCache
();
if
(
mainDb
!=
nullptr
)
{
mainDb
->
disconnect
();
}
}
void
CorePrivate
::
uninit
()
{
L_Q
();
while
(
!
calls
.
empty
())
{
...
...
tester/call_single_tester.c
View file @
3e7baa8a
...
...
@@ -5095,6 +5095,25 @@ end:
linphone_core_manager_destroy
(
marie
);
}
static
void
async_core_stop_after_call
(
void
)
{
LinphoneCoreManager
*
marie
=
linphone_core_manager_new
(
"marie_rc"
);
LinphoneCoreManager
*
pauline
=
linphone_core_manager_new
(
"pauline_rc"
);
BC_ASSERT_TRUE
(
wait_for_until
(
pauline
->
lc
,
NULL
,
&
pauline
->
stat
.
number_of_LinphoneRegistrationOk
,
1
,
2000
));
BC_ASSERT_TRUE
(
wait_for_until
(
pauline
->
lc
,
NULL
,
&
marie
->
stat
.
number_of_LinphoneRegistrationOk
,
1
,
2000
));
BC_ASSERT_TRUE
(
call
(
marie
,
pauline
));
linphone_core_stop_async
(
marie
->
lc
);
BC_ASSERT_EQUAL
(
marie
->
stat
.
number_of_LinphoneGlobalShutdown
,
1
,
int
,
"%d"
);
BC_ASSERT_TRUE
(
wait_for
(
marie
->
lc
,
pauline
->
lc
,
&
marie
->
stat
.
number_of_LinphoneGlobalOff
,
1
));
BC_ASSERT_TRUE
(
wait_for
(
pauline
->
lc
,
NULL
,
&
pauline
->
stat
.
number_of_LinphoneCallEnd
,
1
));
BC_ASSERT_EQUAL
(
marie
->
stat
.
number_of_LinphoneCallEnd
,
1
,
int
,
"%d"
);
linphone_core_manager_destroy_after_stop_async
(
marie
);
linphone_core_manager_destroy
(
pauline
);
}
test_t
call_tests
[]
=
{
TEST_NO_TAG
(
"Early declined call"
,
early_declined_call
),
TEST_NO_TAG
(
"Call declined"
,
call_declined
),
...
...
@@ -5198,6 +5217,7 @@ test_t call_tests[] = {
TEST_NO_TAG
(
"Call declined, other ringing device receive CANCEL with reason"
,
cancel_other_device_after_decline
),
TEST_NO_TAG
(
"Simple call with GRUU"
,
simple_call_with_gruu
),
TEST_NO_TAG
(
"Simple call with GRUU only one device ring"
,
simple_call_with_gruu_only_one_device_ring
),
TEST_ONE_TAG
(
"Async core stop"
,
async_core_stop_after_call
,
"LeaksMemory"
)
};
test_suite_t
call_test_suite
=
{
"Single Call"
,
NULL
,
NULL
,
liblinphone_tester_before_each
,
liblinphone_tester_after_each
,
...
...
tester/liblinphone_tester.h
View file @
3e7baa8a
...
...
@@ -374,11 +374,13 @@ LinphoneCoreManager* linphone_core_manager_new3(const char* rc_file, bool_t chec
LinphoneCoreManager
*
linphone_core_manager_new2
(
const
char
*
rc_file
,
bool_t
check_for_proxies
);
LinphoneCoreManager
*
linphone_core_manager_new
(
const
char
*
rc_file
);
void
linphone_core_manager_stop
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_uninit_after_stop_async
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_reinit
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_restart
(
LinphoneCoreManager
*
mgr
,
bool_t
check_for_proxies
);
void
linphone_core_manager_uninit
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_wait_for_stun_resolution
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_destroy
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_destroy_after_stop_async
(
LinphoneCoreManager
*
mgr
);
void
linphone_core_manager_delete_chat_room
(
LinphoneCoreManager
*
mgr
,
LinphoneChatRoom
*
cr
,
bctbx_list_t
*
coresList
);
bctbx_list_t
*
init_core_for_conference
(
bctbx_list_t
*
coreManagerList
);
void
start_core_for_conference
(
bctbx_list_t
*
coreManagerList
);
...
...
tester/tester.c
View file @
3e7baa8a
...
...
@@ -575,6 +575,22 @@ void linphone_core_manager_stop(LinphoneCoreManager *mgr){
}
}
void
linphone_core_manager_uninit_after_stop_async
(
LinphoneCoreManager
*
mgr
)
{
if
(
mgr
->
lc
)
{
const
char
*
record_file
=
linphone_core_get_record_file
(
mgr
->
lc
);
if
(
!
liblinphone_tester_keep_record_files
&&
record_file
&&
ortp_file_exist
(
record_file
)
==
0
)
{
if
((
bc_get_number_of_failures
()
-
mgr
->
number_of_bcunit_error_at_creation
)
>
0
)
{
ms_error
(
"Test has failed, keeping recorded file [%s]"
,
record_file
);
}
else
{
unlink
(
record_file
);
}
}
linphone_core_unref
(
mgr
->
lc
);
mgr
->
lc
=
NULL
;
}
}
void
linphone_core_manager_reinit
(
LinphoneCoreManager
*
mgr
)
{
char
*
uuid
=
NULL
;
if
(
mgr
->
lc
)
{
...
...
@@ -646,6 +662,17 @@ void linphone_core_manager_destroy(LinphoneCoreManager* mgr) {
ms_free
(
mgr
);
}
void
linphone_core_manager_destroy_after_stop_async
(
LinphoneCoreManager
*
mgr
)
{
if
(
mgr
->
lc
&&
!
linphone_core_is_network_reachable
(
mgr
->
lc
))
{
int
previousNbRegistrationOk
=
mgr
->
stat
.
number_of_LinphoneRegistrationOk
;
linphone_core_set_network_reachable
(
mgr
->
lc
,
TRUE
);
wait_for_until
(
mgr
->
lc
,
NULL
,
&
mgr
->
stat
.
number_of_LinphoneRegistrationOk
,
previousNbRegistrationOk
+
1
,
2000
);
}
linphone_core_manager_uninit_after_stop_async
(
mgr
);
linphone_core_manager_uninit
(
mgr
);
ms_free
(
mgr
);
}
void
linphone_core_manager_delete_chat_room
(
LinphoneCoreManager
*
mgr
,
LinphoneChatRoom
*
cr
,
bctbx_list_t
*
coresList
)
{
stats
mgrStats
=
mgr
->
stat
;
if
(
cr
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment