From: Sangchul Lee Date: Tue, 4 Jan 2022 04:59:54 +0000 (+0900) Subject: Remove event sources not invoked when destroying webrtc handle X-Git-Tag: submit/tizen_6.5/20220107.064135^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a3e7eaebd1ee7200f94a0bc91dec701c1259bfa9;p=platform%2Fcore%2Fapi%2Fwebrtc.git Remove event sources not invoked when destroying webrtc handle A crash can happen with the previous codes. It is fixed by removing event sources of idle callbacks which are not invoked yet before destroying webrtc handle. [Version] 0.2.155 [Issue Type] Bug fix Change-Id: Icff390fdd63ee2aa7bfeedd547d63dbb3e0f5d5a Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index f856e276..6da55eb4 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -401,6 +401,16 @@ typedef struct _webrtc_negotiation_states_s { webrtc_ice_connection_state_e ice_connection_state; } webrtc_negotiation_states_s; +typedef enum _idle_cb_type_e { + IDLE_CB_TYPE_STATE, + IDLE_CB_TYPE_ERROR, + IDLE_CB_TYPE_PEER_CONNECTION_STATE_CHANGE, + IDLE_CB_TYPE_SIGNALING_STATE_CHANGE, + IDLE_CB_TYPE_ICE_GATHERING_STATE_CHANGE, + IDLE_CB_TYPE_ICE_CONNECTION_STATE_CHANGE, + IDLE_CB_TYPE_NUM +} idle_cb_type_e; + typedef struct _webrtc_s { webrtc_ini_s ini; guint stats_timer_src; @@ -426,6 +436,8 @@ typedef struct _webrtc_s { GHashTable *data_channels; GHashTable *track_build_contexts; + guint idle_cb_event_source_ids[IDLE_CB_TYPE_NUM]; + webrtc_callbacks_s error_cb; webrtc_callbacks_s state_changed_cb; webrtc_callbacks_s peer_connection_state_change_cb; @@ -591,6 +603,7 @@ int _push_media_packet(webrtc_s *webrtc, unsigned int source_id, media_packet_h void _invoke_state_changed_cb(webrtc_s *webrtc, webrtc_state_e old, webrtc_state_e new); void _post_state_cb_in_idle(webrtc_s *webrtc, webrtc_state_e new_state); void _post_error_cb_in_idle(webrtc_s *webrtc, webrtc_error_e error); +void _remove_remained_event_sources(webrtc_s *webrtc); void _connect_and_append_signal(GList **signals, GObject *obj, const char *sig_name, GCallback cb, gpointer user_data); void _disconnect_signal(gpointer data); diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 04b557ba..46b83dd9 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -1,6 +1,6 @@ Name: capi-media-webrtc Summary: A WebRTC library in Tizen Native API -Version: 0.2.154 +Version: 0.2.155 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index 540d9f2f..bc424aee 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -128,6 +128,8 @@ int webrtc_destroy(webrtc_h webrtc) locker = g_mutex_locker_new(&_webrtc->mutex); + _remove_remained_event_sources(_webrtc); + _webrtc->pend_state = WEBRTC_STATE_IDLE; _unset_stats_timer(_webrtc); diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 99fea4b8..eebcadf5 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -401,18 +401,9 @@ static gboolean __bus_watch_cb(GstBus *bus, GstMessage *message, gpointer user_d } //LCOV_EXCL_STOP -typedef enum _post_idle_cb_type_e { - POST_IDLE_CB_TYPE_STATE, - POST_IDLE_CB_TYPE_ERROR, - POST_IDLE_CB_TYPE_PEER_CONNECTION_STATE_CHANGE, - POST_IDLE_CB_TYPE_SIGNALING_STATE_CHANGE, - POST_IDLE_CB_TYPE_ICE_GATHERING_STATE_CHANGE, - POST_IDLE_CB_TYPE_ICE_CONNECTION_STATE_CHANGE -} post_idle_cb_type_e; - typedef struct _idle_userdata { webrtc_s *webrtc; - post_idle_cb_type_e type; + idle_cb_type_e type; union { webrtc_state_e state; webrtc_error_e error; @@ -443,11 +434,12 @@ static gboolean __idle_cb(gpointer user_data) webrtc = data->webrtc; switch (data->type) { - case POST_IDLE_CB_TYPE_STATE: { + case IDLE_CB_TYPE_STATE: { webrtc_state_e old_state; g_mutex_lock(&webrtc->mutex); + webrtc->idle_cb_event_source_ids[data->type] = 0; old_state = webrtc->state; webrtc->state = data->new.state; @@ -456,19 +448,24 @@ static gboolean __idle_cb(gpointer user_data) _invoke_state_changed_cb(webrtc, old_state, webrtc->state); break; } - case POST_IDLE_CB_TYPE_ERROR: + case IDLE_CB_TYPE_ERROR: + webrtc->idle_cb_event_source_ids[data->type] = 0; __invoke_error_cb(webrtc, data->new.error); break; - case POST_IDLE_CB_TYPE_PEER_CONNECTION_STATE_CHANGE: + case IDLE_CB_TYPE_PEER_CONNECTION_STATE_CHANGE: + webrtc->idle_cb_event_source_ids[data->type] = 0; __invoke_peer_connection_state_change_cb(webrtc, data->new.peer_connection_state); break; - case POST_IDLE_CB_TYPE_SIGNALING_STATE_CHANGE: + case IDLE_CB_TYPE_SIGNALING_STATE_CHANGE: + webrtc->idle_cb_event_source_ids[data->type] = 0; __invoke_signaling_state_change_cb(webrtc, data->new.signaling_state); break; - case POST_IDLE_CB_TYPE_ICE_GATHERING_STATE_CHANGE: + case IDLE_CB_TYPE_ICE_GATHERING_STATE_CHANGE: + webrtc->idle_cb_event_source_ids[data->type] = 0; __invoke_ice_gathering_state_change_cb(webrtc, data->new.ice_gathering_state); break; - case POST_IDLE_CB_TYPE_ICE_CONNECTION_STATE_CHANGE: + case IDLE_CB_TYPE_ICE_CONNECTION_STATE_CHANGE: + webrtc->idle_cb_event_source_ids[data->type] = 0; __invoke_ice_connection_state_change_cb(webrtc, data->new.ice_connection_state); break; default: @@ -478,6 +475,20 @@ static gboolean __idle_cb(gpointer user_data) return G_SOURCE_REMOVE; } +void _remove_remained_event_sources(webrtc_s *webrtc) +{ + int i; + RET_IF(webrtc == NULL, "webrtc is NULL"); + + for (i = IDLE_CB_TYPE_STATE; i < IDLE_CB_TYPE_NUM; i++) { + if (webrtc->idle_cb_event_source_ids[i] == 0) + continue; + g_source_remove(webrtc->idle_cb_event_source_ids[i]); + LOG_DEBUG("idle_cb_event_source_ids[%d] source id[%u]", i, webrtc->idle_cb_event_source_ids[i]); + webrtc->idle_cb_event_source_ids[i] = 0; + } +} + void _post_state_cb_in_idle(webrtc_s *webrtc, webrtc_state_e new_state) { idle_userdata_s *data; @@ -489,14 +500,15 @@ void _post_state_cb_in_idle(webrtc_s *webrtc, webrtc_state_e new_state) data = g_new0(idle_userdata_s, 1); data->webrtc = webrtc; - data->type = POST_IDLE_CB_TYPE_STATE; + data->type = IDLE_CB_TYPE_STATE; data->new.state = new_state; webrtc->pend_state = new_state; - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); + webrtc->idle_cb_event_source_ids[data->type] = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); - LOG_DEBUG("state will be changed [%s] -> [%s]", __state_str[webrtc->state], __state_str[new_state]); + LOG_DEBUG("state will be changed [%s] -> [%s], source id[%u]", + __state_str[webrtc->state], __state_str[new_state], webrtc->idle_cb_event_source_ids[data->type]); } //LCOV_EXCL_START @@ -508,12 +520,12 @@ void _post_error_cb_in_idle(webrtc_s *webrtc, webrtc_error_e error) data = g_new0(idle_userdata_s, 1); data->webrtc = webrtc; - data->type = POST_IDLE_CB_TYPE_ERROR; + data->type = IDLE_CB_TYPE_ERROR; data->new.error = error; - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); + webrtc->idle_cb_event_source_ids[data->type] = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); - LOG_DEBUG("error will occur [0x%x]", error); + LOG_DEBUG("error will occur [0x%x], source id[%u]", error, webrtc->idle_cb_event_source_ids[data->type]); } static void __post_peer_connection_state_change_cb_in_idle(webrtc_s *webrtc, webrtc_peer_connection_state_e state) @@ -524,12 +536,12 @@ static void __post_peer_connection_state_change_cb_in_idle(webrtc_s *webrtc, web data = g_new0(idle_userdata_s, 1); data->webrtc = webrtc; - data->type = POST_IDLE_CB_TYPE_PEER_CONNECTION_STATE_CHANGE; + data->type = IDLE_CB_TYPE_PEER_CONNECTION_STATE_CHANGE; data->new.peer_connection_state = state; - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); + webrtc->idle_cb_event_source_ids[data->type] = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); - LOG_DEBUG("connection state will be changed to [%u]", state); + LOG_DEBUG("connection state will be changed to [%u], source id[%u]", state, webrtc->idle_cb_event_source_ids[data->type]); } //LCOV_EXCL_STOP @@ -541,12 +553,12 @@ static void __post_signaling_state_change_cb_in_idle(webrtc_s *webrtc, webrtc_si data = g_new0(idle_userdata_s, 1); data->webrtc = webrtc; - data->type = POST_IDLE_CB_TYPE_SIGNALING_STATE_CHANGE; + data->type = IDLE_CB_TYPE_SIGNALING_STATE_CHANGE; data->new.signaling_state = state; - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); + webrtc->idle_cb_event_source_ids[data->type] = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); - LOG_DEBUG("signaling state will be changed to [%u]", state); + LOG_DEBUG("signaling state will be changed to [%u], source id[%u]", state, webrtc->idle_cb_event_source_ids[data->type]); } static void __post_ice_gathering_state_change_cb_in_idle(webrtc_s *webrtc, webrtc_ice_gathering_state_e state) @@ -557,12 +569,12 @@ static void __post_ice_gathering_state_change_cb_in_idle(webrtc_s *webrtc, webrt data = g_new0(idle_userdata_s, 1); data->webrtc = webrtc; - data->type = POST_IDLE_CB_TYPE_ICE_GATHERING_STATE_CHANGE; + data->type = IDLE_CB_TYPE_ICE_GATHERING_STATE_CHANGE; data->new.ice_gathering_state = state; - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); + webrtc->idle_cb_event_source_ids[data->type] = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); - LOG_DEBUG("ICE gathering state will be changed to [%u]", state); + LOG_DEBUG("ICE gathering state will be changed to [%u], source id[%u]", state, webrtc->idle_cb_event_source_ids[data->type]); } //LCOV_EXCL_START @@ -574,12 +586,12 @@ static void __post_ice_connection_state_change_cb_in_idle(webrtc_s *webrtc, webr data = g_new0(idle_userdata_s, 1); data->webrtc = webrtc; - data->type = POST_IDLE_CB_TYPE_ICE_CONNECTION_STATE_CHANGE; + data->type = IDLE_CB_TYPE_ICE_CONNECTION_STATE_CHANGE; data->new.ice_connection_state = state; - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); + webrtc->idle_cb_event_source_ids[data->type] = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); - LOG_DEBUG("ICE connection state will be changed to [%u]", state); + LOG_DEBUG("ICE connection state will be changed to [%u], source id[%u]", state, webrtc->idle_cb_event_source_ids[data->type]); } //LCOV_EXCL_STOP