removed fine grained locking and added simultaneous waiting for 2 states

Original commit message from CVS:
removed fine grained locking and added simultaneous waiting for 2 states
This commit is contained in:
Zaheer Abbas Merali 2001-03-13 01:44:44 +00:00
parent e7b0927f99
commit 03d8077ee2
2 changed files with 49 additions and 12 deletions

View file

@ -70,6 +70,8 @@ static void gst_thread_restore_thyself (GstObject *object, xmlNodePtr self);
static void gst_thread_signal_thread (GstThread *thread, guint syncflag,gboolean set);
static void gst_thread_wait_thread (GstThread *thread, guint syncflag,gboolean set);
static void
gst_thread_wait_two_thread (GstThread *thread, guint syncflag, gboolean set,guint syncflag2, gboolean set2);
static void gst_thread_schedule_dummy (GstBin *bin);
static void* gst_thread_main_loop (void *arg);
@ -130,7 +132,6 @@ gst_thread_class_init (GstThreadClass *klass)
static void
gst_thread_init (GstThread *thread)
{
int i;
GST_DEBUG (0,"initializing thread '%s'\n",GST_ELEMENT_NAME (thread));
@ -140,8 +141,7 @@ gst_thread_init (GstThread *thread)
// default is to create a thread
GST_FLAG_SET (thread, GST_THREAD_CREATE);
for(i=0;i<4;i++)
thread->lock[i] = g_mutex_new();
thread->lock = g_mutex_new();
thread->cond = g_cond_new();
@ -282,9 +282,9 @@ gst_thread_change_state (GstElement *element)
GST_DEBUG(0,"sync: done telling thread to start spinning\n");
GST_INFO(GST_CAT_THREAD, "waiting for thread to start up");
gst_thread_wait_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE);
g_mutex_lock(thread->lock[GST_THREAD_STATE_ELEMENT_CHANGED - GST_THREAD_STATE_STARTED]);
g_mutex_lock(thread->lock);
GST_FLAG_UNSET(thread,GST_THREAD_STATE_ELEMENT_CHANGED);
g_mutex_unlock(thread->lock[GST_THREAD_STATE_ELEMENT_CHANGED - GST_THREAD_STATE_STARTED]);
g_mutex_unlock(thread->lock);
break;
case GST_STATE_PLAYING_TO_PAUSED:
GST_INFO (GST_CAT_THREAD,"pausing thread \"%s\"",
@ -359,9 +359,15 @@ gst_thread_main_loop (void *arg)
}
else {
GST_DEBUG (0, "sync: thread \"%s\" waiting\n", GST_ELEMENT_NAME (GST_ELEMENT (thread)));
gst_thread_wait_thread (thread,GST_THREAD_STATE_SPINNING,TRUE);
gst_thread_wait_two_thread (thread,GST_THREAD_STATE_SPINNING,TRUE,
GST_THREAD_STATE_REAPING,TRUE);
GST_DEBUG (0, "sync: done waiting\n");
// if reaping was returned, break outof while loop
if (GST_FLAG_IS_SET(thread,GST_THREAD_STATE_REAPING)) {
break;
}
// check for state change
if (GST_STATE_PENDING(thread)) {
// punt and change state on all the children
@ -382,14 +388,14 @@ gst_thread_main_loop (void *arg)
static void
gst_thread_signal_thread (GstThread *thread, guint syncflag, gboolean set)
{
g_mutex_lock (thread->lock[syncflag-GST_THREAD_STATE_STARTED]);
g_mutex_lock (thread->lock);
GST_DEBUG (0,"sync: signaling thread setting %u to %d\n",syncflag,set);
if (set)
GST_FLAG_SET(thread,syncflag);
else
GST_FLAG_UNSET(thread,syncflag);
g_cond_signal (thread->cond);
g_mutex_unlock (thread->lock[syncflag-GST_THREAD_STATE_STARTED]);
g_mutex_unlock (thread->lock);
GST_DEBUG (0,"sync: done signaling thread with %u set to %u..should be %d\n",syncflag,
GST_FLAG_IS_SET(thread,syncflag),set);
}
@ -400,7 +406,7 @@ gst_thread_wait_thread (GstThread *thread, guint syncflag, gboolean set)
{
// if (!thread->signaling) {
GTimeVal finaltime;
g_mutex_lock (thread->lock[syncflag-GST_THREAD_STATE_STARTED]);
g_mutex_lock (thread->lock);
GST_DEBUG (0,"sync: waiting for thread for %u to be set %d\n",
syncflag,set);
while ((!GST_FLAG_IS_SET(thread,syncflag) && set==TRUE) ||
@ -413,14 +419,45 @@ gst_thread_wait_thread (GstThread *thread, guint syncflag, gboolean set)
else {
finaltime.tv_usec+=5000;
}
g_cond_timed_wait (thread->cond, thread->lock[syncflag-GST_THREAD_STATE_STARTED],&finaltime);
g_cond_timed_wait (thread->cond, thread->lock,&finaltime);
}
g_mutex_unlock (thread->lock[syncflag-GST_THREAD_STATE_STARTED]);
g_mutex_unlock (thread->lock);
GST_DEBUG (0, "sync: done waiting for thread for %u to be set %d\n",
syncflag,set);
// }
}
// the set flag is to see what flag to wait for
static void
gst_thread_wait_two_thread (GstThread *thread, guint syncflag, gboolean set,
guint syncflag2, gboolean set2)
{
// if (!thread->signaling) {
GTimeVal finaltime;
g_mutex_lock (thread->lock);
GST_DEBUG (0,"sync: waiting for thread for %u to be set %d or %u to be set %d\n",
syncflag,set,syncflag2,set);
while (((!GST_FLAG_IS_SET(thread,syncflag) && set==TRUE) ||
(GST_FLAG_IS_SET(thread,syncflag) && set==FALSE)) &&
((!GST_FLAG_IS_SET(thread,syncflag2) && set2==TRUE) ||
(GST_FLAG_IS_SET(thread,syncflag2) && set==FALSE)))
{
g_get_current_time(&finaltime);
if (finaltime.tv_usec>995000) {
finaltime.tv_sec++;
finaltime.tv_usec=5000-(1000000-finaltime.tv_usec);
}
else {
finaltime.tv_usec+=5000;
}
g_cond_timed_wait (thread->cond, thread->lock,&finaltime);
}
g_mutex_unlock (thread->lock);
GST_DEBUG (0, "sync: done waiting for thread for %u to be set %d or %u to be set %d\n",
syncflag,set,syncflag2,set2);
// }
}
static void
gst_thread_restore_thyself (GstObject *object,

View file

@ -67,7 +67,7 @@ struct _GstThread {
GstBin bin;
pthread_t thread_id; /* id of the thread, if any */
GMutex *lock[4]; /* thread lock/condititon pair... */
GMutex *lock; /* thread lock/condititon pair... */
GCond *cond; /* used to control the thread */
gint transition; /* the current state transition */