mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
fixed another thread synch case... better debug
Original commit message from CVS: fixed another thread synch case... better debug
This commit is contained in:
parent
f3e94925e9
commit
7678183d1a
3 changed files with 103 additions and 29 deletions
|
@ -734,6 +734,7 @@ gst_element_set_state (GstElement *element, GstElementState state)
|
||||||
|
|
||||||
g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
|
g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
|
||||||
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
|
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
|
||||||
|
g_return_val_if_fail (element->sched != NULL, GST_STATE_FAILURE);
|
||||||
|
|
||||||
GST_DEBUG (GST_CAT_STATES,"setting element '%s' to state %s\n",GST_ELEMENT_NAME (element),
|
GST_DEBUG (GST_CAT_STATES,"setting element '%s' to state %s\n",GST_ELEMENT_NAME (element),
|
||||||
_gst_print_statename(state));
|
_gst_print_statename(state));
|
||||||
|
|
|
@ -1281,6 +1281,7 @@ g_return_val_if_fail (chains != NULL, FALSE);
|
||||||
GST_DEBUG (GST_CAT_DATAFLOW,"starting iteration via cothreads\n");
|
GST_DEBUG (GST_CAT_DATAFLOW,"starting iteration via cothreads\n");
|
||||||
|
|
||||||
if (chain->elements) {
|
if (chain->elements) {
|
||||||
|
entry = NULL; //MattH ADDED?
|
||||||
elements = chain->elements;
|
elements = chain->elements;
|
||||||
//printf("searching for non-decoupled element\n");
|
//printf("searching for non-decoupled element\n");
|
||||||
while (elements) {
|
while (elements) {
|
||||||
|
|
130
gst/gstthread.c
130
gst/gstthread.c
|
@ -222,11 +222,14 @@ gst_thread_change_state (GstElement *element)
|
||||||
GstThread *thread;
|
GstThread *thread;
|
||||||
gboolean stateset = GST_STATE_SUCCESS;
|
gboolean stateset = GST_STATE_SUCCESS;
|
||||||
gint transition;
|
gint transition;
|
||||||
|
pthread_t self = pthread_self();
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_THREAD(element), FALSE);
|
g_return_val_if_fail (GST_IS_THREAD(element), FALSE);
|
||||||
GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME(element));
|
GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME(element));
|
||||||
|
|
||||||
thread = GST_THREAD (element);
|
thread = GST_THREAD (element);
|
||||||
|
GST_DEBUG (GST_CAT_THREAD, "**** THREAD %d changing THREAD %d ****\n",self,thread->thread_id);
|
||||||
|
GST_DEBUG (GST_CAT_THREAD, "**** current pid=%d\n",getpid());
|
||||||
|
|
||||||
transition = GST_STATE_TRANSITION (element);
|
transition = GST_STATE_TRANSITION (element);
|
||||||
|
|
||||||
|
@ -278,50 +281,120 @@ gst_thread_change_state (GstElement *element)
|
||||||
GST_INFO (GST_CAT_THREAD, "starting thread \"%s\"",
|
GST_INFO (GST_CAT_THREAD, "starting thread \"%s\"",
|
||||||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||||
|
|
||||||
GST_DEBUG(0,"sync: telling thread to start spinning\n");
|
if (pthread_equal(self, thread->thread_id))
|
||||||
gst_thread_signal_thread(thread,TRUE);
|
{
|
||||||
|
//FIXME this should not happen
|
||||||
|
g_assert(!pthread_equal(self, thread->thread_id));
|
||||||
|
GST_FLAG_SET(thread, GST_THREAD_STATE_SPINNING);
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"no sync: setting own thread's state to spinning\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"sync: telling thread to start spinning\n");
|
||||||
|
g_mutex_lock(thread->lock);
|
||||||
|
gst_thread_signal_thread(thread,TRUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PLAYING_TO_PAUSED:
|
case GST_STATE_PLAYING_TO_PAUSED:
|
||||||
GST_INFO (GST_CAT_THREAD,"pausing thread \"%s\"",
|
GST_INFO (GST_CAT_THREAD,"pausing thread \"%s\"",
|
||||||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||||
|
|
||||||
// the following code ensures that the bottom half of thread will run
|
|
||||||
// to perform each elements' change_state() (by calling gstbin.c::
|
if (pthread_equal(self, thread->thread_id))
|
||||||
// change_state()).
|
|
||||||
// + the pending state was already set by gstelement.c::set_state()
|
|
||||||
// + find every queue we manage, and signal its empty and full conditions
|
|
||||||
{
|
{
|
||||||
GList *elements = (element->sched)->elements;
|
//FIXME this should not happen
|
||||||
while (elements)
|
g_assert(!pthread_equal(self, thread->thread_id));
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"no sync: setting own thread's state to paused\n");
|
||||||
|
GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
GstElement *e = GST_ELEMENT(elements->data);
|
GList *elements = (element->sched)->elements;
|
||||||
g_assert(e);
|
|
||||||
elements = g_list_next(elements);
|
// the following code ensures that the bottom half of thread will run
|
||||||
if (GST_IS_QUEUE(e))
|
// to perform each elements' change_state() (by calling gstbin.c::
|
||||||
|
// change_state()).
|
||||||
|
// + the pending state was already set by gstelement.c::set_state()
|
||||||
|
// + find every queue we manage, and signal its empty and full conditions
|
||||||
|
g_mutex_lock(thread->lock);
|
||||||
|
while (elements)
|
||||||
{
|
{
|
||||||
//FIXME make this more efficient by only waking queues that are asleep
|
GstElement *e = GST_ELEMENT(elements->data);
|
||||||
//FIXME and only waking the appropriate condition (depending on if it's
|
g_assert(e);
|
||||||
//FIXME on up- or down-stream side)
|
GST_DEBUG(GST_CAT_THREAD," element %s\n",GST_ELEMENT_NAME(e));
|
||||||
//
|
elements = g_list_next(elements);
|
||||||
//FIXME also make this more efficient by keeping list of managed queues
|
if (GST_IS_QUEUE(e))
|
||||||
g_cond_signal((GST_QUEUE(e)->emptycond));
|
{
|
||||||
g_cond_signal((GST_QUEUE(e)->fullcond));
|
//FIXME make this more efficient by only waking queues that are asleep
|
||||||
|
//FIXME and only waking the appropriate condition (depending on if it's
|
||||||
|
//FIXME on up- or down-stream side)
|
||||||
|
//
|
||||||
|
//FIXME also make this more efficient by keeping list of managed queues
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"sync: waking queue \"%s\"\n",
|
||||||
|
GST_ELEMENT_NAME(e));
|
||||||
|
g_cond_signal((GST_QUEUE(e)->emptycond));
|
||||||
|
g_cond_signal((GST_QUEUE(e)->fullcond));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GList *pads = GST_ELEMENT_PADS(e);
|
||||||
|
while (pads)
|
||||||
|
{
|
||||||
|
GstPad *p = GST_PAD(pads->data);
|
||||||
|
pads = g_list_next(pads);
|
||||||
|
if (GST_IS_REAL_PAD(p) &&
|
||||||
|
GST_ELEMENT_SCHED(e) != GST_ELEMENT_SCHED(GST_ELEMENT(GST_PAD_PARENT(GST_PAD_PEER(p)))))
|
||||||
|
{
|
||||||
|
GST_DEBUG(GST_CAT_THREAD," element \"%s\" has pad cross sched boundary\n",GST_ELEMENT_NAME(e));
|
||||||
|
// FIXME i assume this signals our own (current) thread so don't need to lock
|
||||||
|
// FIXME however, this *may* go to yet another thread for which we need locks
|
||||||
|
// FIXME i'm too tired to deal with this now
|
||||||
|
g_cond_signal(GST_QUEUE(GST_ELEMENT(GST_PAD_PARENT(GST_PAD_PEER(p))))->emptycond);
|
||||||
|
g_cond_signal(GST_QUEUE(GST_ELEMENT(GST_PAD_PARENT(GST_PAD_PEER(p))))->fullcond);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"sync: telling thread to pause\n");
|
||||||
|
gst_thread_signal_thread(thread,FALSE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
gst_thread_signal_thread(thread,FALSE);
|
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PLAYING_TO_READY:
|
case GST_STATE_PLAYING_TO_READY:
|
||||||
gst_thread_signal_thread(thread,FALSE);
|
if (pthread_equal(self, thread->thread_id))
|
||||||
|
{
|
||||||
|
//FIXME this should not happen
|
||||||
|
g_assert(!pthread_equal(self, thread->thread_id));
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"no sync: setting own thread's state to ready (paused)\n");
|
||||||
|
GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"sync: telling thread to pause (ready)\n");
|
||||||
|
g_mutex_lock(thread->lock);
|
||||||
|
gst_thread_signal_thread(thread,FALSE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_READY_TO_NULL:
|
||||||
GST_INFO (GST_CAT_THREAD,"stopping thread \"%s\"",
|
GST_INFO (GST_CAT_THREAD,"stopping thread \"%s\"",
|
||||||
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
GST_ELEMENT_NAME (GST_ELEMENT (element)));
|
||||||
|
|
||||||
GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
|
GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
|
||||||
gst_thread_signal_thread(thread,FALSE);
|
if (pthread_equal(self, thread->thread_id))
|
||||||
|
{
|
||||||
pthread_join(thread->thread_id,NULL);
|
//FIXME this should not happen
|
||||||
|
g_assert(!pthread_equal(self, thread->thread_id));
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"no sync: setting own thread's state to NULL (paused)\n");
|
||||||
|
GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GST_DEBUG(GST_CAT_THREAD,"sync: telling thread to pause (null) - and joining\n");
|
||||||
|
//MattH FIXME revisit
|
||||||
|
// g_mutex_lock(thread->lock);
|
||||||
|
// gst_thread_signal_thread(thread,FALSE);
|
||||||
|
pthread_join(thread->thread_id,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
|
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
|
||||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_STARTED);
|
GST_FLAG_UNSET(thread,GST_THREAD_STATE_STARTED);
|
||||||
|
@ -360,7 +433,6 @@ static void *
|
||||||
gst_thread_main_loop (void *arg)
|
gst_thread_main_loop (void *arg)
|
||||||
{
|
{
|
||||||
GstThread *thread = GST_THREAD (arg);
|
GstThread *thread = GST_THREAD (arg);
|
||||||
gboolean first = 1;
|
|
||||||
gint stateset;
|
gint stateset;
|
||||||
|
|
||||||
GST_INFO (GST_CAT_THREAD,"thread \"%s\" is running with PID %d",
|
GST_INFO (GST_CAT_THREAD,"thread \"%s\" is running with PID %d",
|
||||||
|
@ -434,8 +506,8 @@ gst_thread_signal_thread (GstThread *thread, gboolean spinning)
|
||||||
if (spinning) GST_FLAG_SET(thread,GST_THREAD_STATE_SPINNING);
|
if (spinning) GST_FLAG_SET(thread,GST_THREAD_STATE_SPINNING);
|
||||||
else GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
|
else GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
|
||||||
|
|
||||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: locking\n");
|
GST_DEBUG (GST_CAT_THREAD, "sync-main: thread locked\n");
|
||||||
g_mutex_lock(thread->lock);
|
// g_mutex_lock(thread->lock);
|
||||||
|
|
||||||
if (!spinning) {
|
if (!spinning) {
|
||||||
GST_DEBUG (GST_CAT_THREAD, "sync-main: waiting for spindown\n");
|
GST_DEBUG (GST_CAT_THREAD, "sync-main: waiting for spindown\n");
|
||||||
|
|
Loading…
Reference in a new issue