amldemux: CB1 fix amldmxwrap close deadlock [1/1]
PD#SWPL-134812
Problem:
amldmxwrap close deadlock
amldmxwrap data thread can't exit when get es
Solution:
add protection in get es interface
Verify:
(detail info)
Change-Id: If192fa114f2c63380570a2f8eb46f8944a9eec86
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/src/gstamldmx.c b/src/gstamldmx.c
index 57c64ee..801f2b0 100644
--- a/src/gstamldmx.c
+++ b/src/gstamldmx.c
@@ -1556,11 +1556,8 @@
{
GST_DEBUG_OBJECT(amlhwdmx, "probe done. restarting es filters");
- gst_amldmxwrap_stop_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid);
- for (gint i = 0; i < amlhwdmx->sinkpad.pat_para.pat.program_num; i++)
- {
- gst_amldmxwrap_stop_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pmt_para[i].fid);
- }
+ gst_pmt_filter_reset(amlhwdmx);
+ gst_pat_filter_reset(amlhwdmx);
gst_amlhwdmx_start_es_streams(amlhwdmx);
amlhwdmx->flags &= ~GST_AML_DMX_PROB_DONE;
diff --git a/src/gstamldmxwrap.c b/src/gstamldmxwrap.c
index d8973d0..dee9fe5 100644
--- a/src/gstamldmxwrap.c
+++ b/src/gstamldmxwrap.c
@@ -40,6 +40,24 @@
#define SEC_BUF_HEADER_SIZE (40)
#define DMX_POLL_TIMEOUT (200)
+#define AMLHWDMXWRAP_GET_LOCK(dev) (&((dev)->lock))
+#define AMLHWDMXWRAP_CONTEXT_LOCK(dev) \
+ G_STMT_START \
+ { \
+ GST_TRACE("Locking amldmxwrap lock from thread %p", g_thread_self()); \
+ g_mutex_lock(AMLHWDMXWRAP_GET_LOCK(dev)); \
+ GST_TRACE("Locked amldmxwrap lock from thread %p", g_thread_self()); \
+ } \
+ G_STMT_END
+#define AMLHWDMXWRAP_CONTEXT_UNLOCK(dev) \
+ G_STMT_START \
+ { \
+ GST_TRACE("Unlocking amldmxwrap lock from thread %p", g_thread_self()); \
+ g_mutex_unlock(AMLHWDMXWRAP_GET_LOCK(dev)); \
+ GST_TRACE("Unlocked amldmxwrap lock from thread %p", g_thread_self()); \
+ } \
+ G_STMT_END
+
typedef struct
{
gint dev_no;
@@ -118,7 +136,7 @@
cnt = 0;
mask = 0;
- g_mutex_lock(&dmx->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dmx);
for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
{
if (dmx->filter[fid].need_free)
@@ -143,7 +161,7 @@
}
}
- g_mutex_unlock(&dmx->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dmx);
if (!cnt)
{
@@ -162,7 +180,7 @@
{
if (fds[i].revents & (POLLIN | POLLERR))
{
- g_mutex_lock(&dmx->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dmx);
filter = &dmx->filter[fids[i]];
if (!filter->enable || !filter->used || filter->need_free)
{
@@ -185,7 +203,7 @@
GST_DEBUG("read demux filter[%d] failed (%s) %d", fids[i], strerror(errno), errno);
}
}
- g_mutex_unlock(&dmx->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dmx);
GST_DEBUG("tid[%x] ch[%d] %x bytes", sec_buf[0], fids[i], len);
if (len > 0 && filter->cb)
{
@@ -200,6 +218,8 @@
free(sec_buf);
}
+ GST_DEBUG("trace out data thread");
+
return NULL;
}
@@ -416,7 +436,7 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = &dev->filter[0];
for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
{
@@ -429,7 +449,7 @@
if (fid >= DMX_FILTER_COUNT)
{
GST_DEBUG("filter id:%d, have no filter to alloc", fid);
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
return DVB_FAILURE;
}
@@ -439,7 +459,7 @@
if (fd == -1)
{
GST_DEBUG("cannot open \"%s\" (%s)", dev_name, strerror(errno));
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
return DVB_FAILURE;
}
@@ -449,7 +469,7 @@
filter[fid].used = 1;
*fhandle = fid;
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
// GST_DEBUG("fhandle = %d", fid);
return DVB_SUCCESS;
@@ -476,7 +496,7 @@
if (!params)
return DVB_FAILURE;
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -493,7 +513,7 @@
}
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
// GST_DEBUG("pid = %x", params->pid);
return ret;
}
@@ -519,7 +539,7 @@
if (!params)
return DVB_FAILURE;
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -544,7 +564,7 @@
}
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
// GST_DEBUG("pid = %x", params->pid);
return ret;
}
@@ -567,7 +587,7 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -579,7 +599,7 @@
}
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
return ret;
}
@@ -599,7 +619,7 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -607,7 +627,7 @@
filter->need_free = 1;
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
// GST_DEBUG("fhandle = %d", fhandle);
return DVB_SUCCESS;
@@ -631,7 +651,7 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter && !filter->enable)
@@ -647,7 +667,7 @@
}
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
gst_aml_dmabuf_mgr_set_filter_info(fhandle, filter->fd, 0);
@@ -671,7 +691,7 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter && filter->enable)
@@ -687,7 +707,7 @@
}
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
gst_aml_dmabuf_mgr_set_filter_info(fhandle, filter->fd, 1);
@@ -713,7 +733,7 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
filter = dmx_get_filter(dev, fhandle);
if (filter)
{
@@ -725,7 +745,7 @@
ret = DVB_FAILURE;
}
- g_mutex_unlock(&dev->lock);
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
// GST_DEBUG("ret = %d", ret);
return ret;
@@ -751,8 +771,9 @@
return DVB_FAILURE;
}
- g_mutex_lock(&dev->lock);
+ gst_amldmxwrap_set_flushing(dev_no, TRUE);
+ AMLHWDMXWRAP_CONTEXT_LOCK(dev);
for (i = 0; i < DMX_FILTER_COUNT; i++)
{
filter = &dev->filter[i];
@@ -773,14 +794,13 @@
open_count++;
}
}
+ AMLHWDMXWRAP_CONTEXT_UNLOCK(dev);
if (open_count == 0)
{
g_atomic_int_set(&dev->running, 0);
gst_task_stop(dev->task);
- g_rec_mutex_lock(&dev->tlock);
- g_rec_mutex_unlock(&dev->tlock);
gst_task_join(dev->task);
gst_object_unref(dev->task);
g_rec_mutex_clear(&dev->tlock);
@@ -799,7 +819,6 @@
dev->dmx_src_fd = -1;
}
- GST_INFO("trace out");
return ret;
}
@@ -808,6 +827,7 @@
dvb_dmx_t *dmx = NULL;
dvb_dmx_filter_t *filter = NULL;
gint ret = 0;
+ DVB_RESULT dmxret = DVB_SUCCESS;
struct pollfd fd[1];
GST_DEBUG("need read size:%d", size);
@@ -815,17 +835,17 @@
if (dmx_get_dev(dev_no, &dmx))
{
GST_ERROR("get dmx error");
- return DVB_FAILURE;
+ goto fail;
}
filter = &dmx->filter[fhandle];
if (!filter || !filter->enable || !filter->used || filter->need_free)
{
GST_ERROR("ch[%d] not used, not read", fhandle);
- return DVB_FAILURE;
+ goto fail;
}
- while (1)
+ while (g_atomic_int_get(&dmx->running))
{
memset(fd, 0, sizeof(struct pollfd));
fd[0].events = POLLIN | POLLERR;
@@ -836,7 +856,7 @@
if (!g_atomic_int_get(&dmx->running))
{
GST_DEBUG("flushing");
- return DVB_SUCCESS;
+ goto done;
}
GST_DEBUG("poll ret:%d timeout. need continue", ret);
@@ -845,8 +865,6 @@
if (fd[0].revents & (POLLIN | POLLERR))
{
- // pthread_mutex_lock(&dmx->lock);
-
gint tmp = 0;
guint read_len = 0;
guint left = size;
@@ -856,7 +874,7 @@
if (tmp <= 0)
{
GST_ERROR("read demux filter[%d] failed (%s) %d", fhandle, strerror(errno), errno);
- return DVB_FAILURE;
+ goto fail;
}
read_len += tmp;
left -= tmp;
@@ -865,12 +883,16 @@
GST_DEBUG("read demux filter[%d] ok", fhandle);
- // pthread_mutex_unlock(&dmx->lock);
break;
}
}
- return DVB_SUCCESS;
+done:
+ GST_DEBUG("read ret:%d", ret);
+ return dmxret;
+fail:
+ dmxret = DVB_FAILURE;
+ goto done;
}
DVB_RESULT gst_amldmxwrap_get_filters_mem_info(gint dev_no, struct dmx_filter_mem_info *info_all)