Remove event sources not invoked when destroying webrtc handle 24/268924/2 submit/tizen_6.5/20220107.064135
authorSangchul Lee <sc11.lee@samsung.com>
Tue, 4 Jan 2022 04:59:54 +0000 (13:59 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 6 Jan 2022 09:39:32 +0000 (18:39 +0900)
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 <sc11.lee@samsung.com>
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc.c
src/webrtc_private.c

index f856e27674247ca4ef253147c049bc04ba57b7b6..6da55eb4e6b26693c8ceb506fe4ea23e6eb2fec6 100644 (file)
@@ -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);
index 04b557ba5a9445b119125bd749b9c255cdb6cbbd..46b83dd96200dbef0683bb11b75e5d4d7d22c790 100644 (file)
@@ -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
index 540d9f2fb66aa167091827f3f86bd82083b9fb0f..bc424aee65f39e01ca5397359a4793826f03c9ac 100644 (file)
@@ -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);
index 99fea4b81a0a2cd44b496c3c4732657621e469e1..eebcadf5af067580997b6383bbcea2fbf626eba5 100644 (file)
@@ -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