}
}
+static void __release_data_channel(webrtc_data_channel_s *channel)
+{
+ RET_IF(channel == NULL, "channel is NULL");
+
+ g_mutex_lock(&channel->mutex);
+
+ g_list_free_full(channel->signals, _disconnect_signal);
+ channel->signals = NULL;
+
+ LOG_DEBUG("channel[%p, object:%p, webrtc:%p] is released", channel, channel->channel, channel->webrtc);
+
+ gst_object_unref(channel->channel);
+
+ g_mutex_unlock(&channel->mutex);
+ g_mutex_clear(&channel->mutex);
+
+ g_free(channel);
+}
+
static void __data_channel_on_close_cb(GObject *data_channel, gpointer user_data)
{
webrtc_data_channel_s *channel = (webrtc_data_channel_s *)user_data;
((webrtc_data_channel_close_cb)(channel->close_cb.callback))((webrtc_data_channel_h)channel, channel->close_cb.user_data);
LOG_DEBUG("<<< end of the callback");
}
+
+ if (channel->removed_from_table) /* in case that it is in the middle of destroying handle */
+ __release_data_channel(channel);
}
//LCOV_EXCL_STOP
RET_IF(webrtc == NULL, "webrtc is NULL");
+ /* FIXME: unify calling gst_object_ref() or not with in _create_data_channel() together
+ * after fixing webrtcbin issue. */
if (!(channel = __prepare_data_channel(webrtc, gst_object_ref(data_channel))))
return;
+ channel->from_remote = true;
+
LOG_INFO("data channel[%p, object:%p, label:%s] is created by remote request",
channel, data_channel, GST_OBJECT_NAME(data_channel));
int _destroy_data_channel(webrtc_data_channel_s *channel)
{
RET_VAL_IF(channel == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "channel is NULL");
- RET_VAL_IF(channel->webrtc == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtc is NULL");
+ RET_VAL_IF(channel->from_remote, WEBRTC_ERROR_INVALID_PARAMETER, "do not destroy a data channel obtained from _on_data_channel_cb()");
g_hash_table_remove(channel->webrtc->data_channels, channel);
return WEBRTC_ERROR_NONE;
}
-static int __unprepare_data_channel(webrtc_data_channel_s *channel)
+static bool __unprepare_data_channel(webrtc_data_channel_s *channel)
{
GstWebRTCDataChannelState state;
- RET_VAL_IF(channel == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "channel is NULL");
+ RET_VAL_IF(channel == NULL, false, "channel is NULL");
g_mutex_lock(&channel->mutex);
-
g_object_get(channel->channel, "ready-state", &state, NULL);
+ channel->removed_from_table = true;
+ g_mutex_unlock(&channel->mutex);
if (state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
LOG_DEBUG("request to close channel[%p, %p]", channel, channel->channel);
+ /* do __release_data_channel() in __data_channel_on_close_cb() */
g_signal_emit_by_name(channel->channel, "close");
+ return false;
}
- g_list_free_full(channel->signals, _disconnect_signal);
- channel->signals = NULL;
-
- LOG_DEBUG("channel[%p, object:%p, webrtc:%p] is unprepared", channel, channel->channel, channel->webrtc);
-
- gst_object_unref(channel->channel);
-
- g_mutex_unlock(&channel->mutex);
- g_mutex_clear(&channel->mutex);
-
- g_free(channel);
-
- return WEBRTC_ERROR_NONE;
+ return true;
}
static void __data_channel_destroy_cb(gpointer data)
RET_IF(data_channel == NULL, "data_channel is NULL");
- __unprepare_data_channel(data_channel);
+ if (__unprepare_data_channel(data_channel))
+ __release_data_channel(data_channel);
}
void _init_data_channels(webrtc_s *webrtc)
RET_IF(!g_conns[index].webrtc, "webrtc is NULL");
+ for (i = 0; i < MAX_CHANNEL_LEN; i++) {
+ if (g_conns[index].channels[i]) {
+ webrtc_destroy_data_channel(g_conns[index].channels[i]);
+ g_conns[index].channels[i] = NULL;
+ }
+ g_conns[index].recv_channels[i] = NULL;
+ }
+
ret = webrtc_destroy(g_conns[index].webrtc);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
g_list_free_full(g_conns[index].ice_candidates, free);
g_conns[index].ice_candidates = NULL;
- for (i = 0; i < MAX_CHANNEL_LEN; i++) {
- if (g_conns[index].channels[i] != NULL)
- g_conns[index].channels[i] = NULL;
- if (g_conns[index].recv_channels[i] != NULL)
- g_conns[index].recv_channels[i] = NULL;
- }
g_conns[index].channel_index = 0;
for (i = 0; i < MAX_MEDIA_PACKET_SOURCE_LEN; i++)
}
g_conns[index].channel_index = 0;
- for (i = 0; i < MAX_CHANNEL_LEN; i++) {
- if (g_conns[index].recv_channels[i] == NULL)
- continue;
- ret = webrtc_destroy_data_channel(g_conns[index].recv_channels[i]);
- if (ret != WEBRTC_ERROR_NONE) {
- g_print("failed to _webrtc_destroy_data_channel(), index[%d]\n", i);
- } else {
- g_print("_webrtc_destroy_data_channel() success, receive channel index[%d]\n", i);
- g_conns[index].recv_channels[i] = NULL;
- }
- }
+ for (i = 0; i < MAX_CHANNEL_LEN; i++)
+ g_conns[index].recv_channels[i] = NULL;
}
static void _webrtc_data_channel_get_label(int index)