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_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_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_schedule_dummy (GstBin *bin);
static void* gst_thread_main_loop (void *arg); static void* gst_thread_main_loop (void *arg);
@ -130,7 +132,6 @@ gst_thread_class_init (GstThreadClass *klass)
static void static void
gst_thread_init (GstThread *thread) gst_thread_init (GstThread *thread)
{ {
int i;
GST_DEBUG (0,"initializing thread '%s'\n",GST_ELEMENT_NAME (thread)); 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 // default is to create a thread
GST_FLAG_SET (thread, GST_THREAD_CREATE); GST_FLAG_SET (thread, GST_THREAD_CREATE);
for(i=0;i<4;i++) thread->lock = g_mutex_new();
thread->lock[i] = g_mutex_new();
thread->cond = g_cond_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_DEBUG(0,"sync: done telling thread to start spinning\n");
GST_INFO(GST_CAT_THREAD, "waiting for thread to start up"); GST_INFO(GST_CAT_THREAD, "waiting for thread to start up");
gst_thread_wait_thread (thread,GST_THREAD_STATE_ELEMENT_CHANGED,TRUE); 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); 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; 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\"",
@ -359,9 +359,15 @@ gst_thread_main_loop (void *arg)
} }
else { else {
GST_DEBUG (0, "sync: thread \"%s\" waiting\n", GST_ELEMENT_NAME (GST_ELEMENT (thread))); 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"); 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 // check for state change
if (GST_STATE_PENDING(thread)) { if (GST_STATE_PENDING(thread)) {
// punt and change state on all the children // punt and change state on all the children
@ -382,14 +388,14 @@ gst_thread_main_loop (void *arg)
static void static void
gst_thread_signal_thread (GstThread *thread, guint syncflag, gboolean set) 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); GST_DEBUG (0,"sync: signaling thread setting %u to %d\n",syncflag,set);
if (set) if (set)
GST_FLAG_SET(thread,syncflag); GST_FLAG_SET(thread,syncflag);
else else
GST_FLAG_UNSET(thread,syncflag); GST_FLAG_UNSET(thread,syncflag);
g_cond_signal (thread->cond); 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_DEBUG (0,"sync: done signaling thread with %u set to %u..should be %d\n",syncflag,
GST_FLAG_IS_SET(thread,syncflag),set); GST_FLAG_IS_SET(thread,syncflag),set);
} }
@ -400,7 +406,7 @@ gst_thread_wait_thread (GstThread *thread, guint syncflag, gboolean set)
{ {
// if (!thread->signaling) { // if (!thread->signaling) {
GTimeVal finaltime; 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", GST_DEBUG (0,"sync: waiting for thread for %u to be set %d\n",
syncflag,set); syncflag,set);
while ((!GST_FLAG_IS_SET(thread,syncflag) && set==TRUE) || while ((!GST_FLAG_IS_SET(thread,syncflag) && set==TRUE) ||
@ -413,14 +419,45 @@ gst_thread_wait_thread (GstThread *thread, guint syncflag, gboolean set)
else { else {
finaltime.tv_usec+=5000; 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", GST_DEBUG (0, "sync: done waiting for thread for %u to be set %d\n",
syncflag,set); 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 static void
gst_thread_restore_thyself (GstObject *object, gst_thread_restore_thyself (GstObject *object,

View file

@ -67,7 +67,7 @@ struct _GstThread {
GstBin bin; GstBin bin;
pthread_t thread_id; /* id of the thread, if any */ 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 */ GCond *cond; /* used to control the thread */
gint transition; /* the current state transition */ gint transition; /* the current state transition */