Revision: 7296
          http://playerstage.svn.sourceforge.net/playerstage/?rev=7296&view=rev
Author:   thjc
Date:     2009-01-24 04:43:40 +0000 (Sat, 24 Jan 2009)

Log Message:
-----------
replace pthread_barrier use with custom barrier build on mutex/cond variables

Modified Paths:
--------------
    code/player/trunk/libplayercore/driver.h
    code/player/trunk/libplayercore/threaded_driver.cc

Modified: code/player/trunk/libplayercore/driver.h
===================================================================
--- code/player/trunk/libplayercore/driver.h    2009-01-24 02:25:59 UTC (rev 
7295)
+++ code/player/trunk/libplayercore/driver.h    2009-01-24 04:43:40 UTC (rev 
7296)
@@ -106,7 +106,7 @@
        int subscriptions;
   public:
     bool HasSubscriptions();
-    
+
   protected:
 
     /** @brief Add an interface.
@@ -154,23 +154,23 @@
     /** @brief Mutex used to protect the subscription count for the driver. */
     pthread_mutex_t subscriptionMutex;
   protected:
-    /** @brief Lock access between the server and driver threads. In 
particular used 
+    /** @brief Lock access between the server and driver threads. In 
particular used
      * to procect the drivers thread pointer */
-     virtual void Lock(void); 
+     virtual void Lock(void);
     /** @brief Unlock access to driver internals. */
     virtual void Unlock(void);
-    
+
     /** @brief Lock to protect the subscription count for the driver */
-     virtual void SubscriptionLock(void); 
+     virtual void SubscriptionLock(void);
     /** @brief Unlock to protect the subscription count for the driver. */
     virtual void SubscriptionUnlock(void);
 
-    /** enable thread cancellation and test for cancellation 
-     * 
+    /** enable thread cancellation and test for cancellation
+     *
      * This should only ever be called from the driver thread with *no* locks 
held*/
     virtual void TestCancel() {};
-    
-    
+
+
   public:
     /** @brief Last requester's queue.
 
@@ -360,8 +360,8 @@
 
     @returns Returns 0 on success. */
     virtual int Terminate();
-    
-    
+
+
     /** @brief Initialize the driver.
 
     This function is called with the first client subscribes; it MUST
@@ -448,8 +448,50 @@
        PLAYER_THREAD_STATE_RESTARTING
 } player_thread_state_t;
 
+class PlayerBarrier
+{
+public:
+       PlayerBarrier()
+       {
+               pthread_mutex_init(&barrierMutex,NULL);
+               pthread_cond_init(&barrierCond,NULL);
+               barrierValue = 0;
+       }
+       ~PlayerBarrier()
+       {
+               pthread_mutex_destroy(&barrierMutex);
+               pthread_cond_destroy(&barrierCond);
+       };
 
+       int SetValue(int Value)
+       {
+               return barrierValue = Value;
+       };
 
+       int Wait()
+       {
+               pthread_mutex_lock(&barrierMutex);
+               assert(barrierValue);
+               if (--barrierValue)
+                       pthread_cond_wait(&barrierCond,&barrierMutex);
+               else
+                       pthread_cond_broadcast(&barrierCond);
+               pthread_mutex_unlock(&barrierMutex);
+               return 0;
+       };
+private:
+    /** @brief barrier to make sure StartThread doesnt return until
+    * cleanup handlers etc have been installed.*/
+    pthread_mutex_t barrierMutex;
+
+    int barrierValue;
+
+    pthread_cond_t barrierCond;
+
+};
+
+
+
 /**
 @brief Base class for drivers which oeprate with a thread.
 
@@ -462,7 +504,7 @@
 coming from the deferred cancellation.
 
 The default setup method simply calls StartThread and likewise the default 
Shutdown method calls
-StopThread. Resources for the driver should be allocated in MainSetup and 
cleaned up in MainQuit, these 
+StopThread. Resources for the driver should be allocated in MainSetup and 
cleaned up in MainQuit, these
 two methods will be called in the driver thread before and after the main 
method respectively.
 
 When StopThread is called it will request the driver thread to be cancelled, 
this cancellation will be
@@ -480,7 +522,7 @@
 
 From the RUNNING state the driver can transition to STOPPING, triggered by a 
call to StopThread.
 
-In the STOPPING state the driver can transition to STOPPED, triggered by 
MainQuit running, or to RESTARTING on a call to 
+In the STOPPING state the driver can transition to STOPPED, triggered by 
MainQuit running, or to RESTARTING on a call to
 StartThread.
 
 From RESTARTING the driver can transition to RUNNING once MainQuit has run and 
the new thread is started, or to STOPPING if
@@ -516,36 +558,36 @@
     The driver's thread, when managed by StartThread() and
     StopThread(). */
     pthread_t driverthread;
-    
+
     /** @brief TODO: insert state machine here
     . */
     player_thread_state_t ThreadState;
     bool SetupSuccessful;
-    /** @brief barrier to make sure StartThread doesnt return until  
-    * cleanup handlers etc have been installed.*/
-    pthread_barrier_t threadSetupBarrier;
-    
+
+    /// Barrier to synchronise threads on setup
+    PlayerBarrier SetupBarrier;
+
   protected:
-    /** enable thread cancellation and test for cancellation 
-     * 
+    /** enable thread cancellation and test for cancellation
+     *
      * This should only ever be called from the driver thread with *no* locks 
held*/
     void TestCancel();
-    
-    
+
+
   public:
-       
+
        /** @brief Constructor with implicit interface
         @param cf Current configuration file
         @param section Current section in configuration file
         @param overwrite_cmds Do new commands overwrite old ones?
-        @param queue_maxlen How long can the incoming queue grow? 
+        @param queue_maxlen How long can the incoming queue grow?
         @param interface The interface that you want this driver to provide*/
         ThreadedDriver(ConfigFile *cf,
                        int section,
                        bool overwrite_cmds,
                        size_t queue_maxlen,
                        int interface);
-        
+
     /** @brief Constructor for multiple-interface drivers.
 
     Use AddInterface() to specify individual interfaces.
@@ -594,7 +636,7 @@
 
     /** @brief Sets up the resources needed by the driver thread */
     virtual int MainSetup(void) {return 0;};
-    
+
     /** @brief Cleanup method for driver thread (called when main exits)
 
     Overload this method and to do additional cleanup when the
@@ -610,11 +652,11 @@
     If TimeOut is set to a positive value this method will return false if the
     timeout occurs before and update is recieved.
     */
-    bool Wait(double TimeOut=0.0);    
+    bool Wait(double TimeOut=0.0);
 
     virtual void Update()
     {};
-    
+
 };
 
 

Modified: code/player/trunk/libplayercore/threaded_driver.cc
===================================================================
--- code/player/trunk/libplayercore/threaded_driver.cc  2009-01-24 02:25:59 UTC 
(rev 7295)
+++ code/player/trunk/libplayercore/threaded_driver.cc  2009-01-24 04:43:40 UTC 
(rev 7296)
@@ -74,7 +74,6 @@
        driverthread(0),
        ThreadState(PLAYER_THREAD_STATE_STOPPED)
 {
-       pthread_barrier_init(&threadSetupBarrier, NULL,2);
 }
 
 // this is the other constructor, used by multi-interface drivers.
@@ -83,7 +82,6 @@
        driverthread(0),
        ThreadState(PLAYER_THREAD_STATE_STOPPED)
 {
-       pthread_barrier_init(&threadSetupBarrier, NULL,2);
 }
 
 // destructor, to free up allocated queue.
@@ -100,7 +98,6 @@
                usleep(100000);
        }
 
-       pthread_barrier_destroy(&threadSetupBarrier);
 }
 
 void ThreadedDriver::TestCancel()
@@ -117,10 +114,11 @@
 {
   if (ThreadState == PLAYER_THREAD_STATE_STOPPED)
   {
+    SetupBarrier.SetValue(2);
     pthread_create(&driverthread, NULL, &DummyMain, this);
 
     // sync with dummy main
-    pthread_barrier_wait(&threadSetupBarrier);
+    SetupBarrier.Wait();
     ThreadState = PLAYER_THREAD_STATE_RUNNING;
   }
   else if (ThreadState == PLAYER_THREAD_STATE_STOPPING)
@@ -166,17 +164,18 @@
 
   // Defer initalisation
   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
-  ((ThreadedDriver*)devicep)->SetupSuccessful = false;
+  ThreadedDriver &tdriver = *reinterpret_cast<ThreadedDriver*>(devicep);
+  tdriver.SetupSuccessful = false;
   // sync with start thread
-  pthread_barrier_wait(&((ThreadedDriver*)devicep)->threadSetupBarrier);
+  tdriver.SetupBarrier.Wait();
 
   pthread_cleanup_push(&DummyMainQuit, devicep);
-  int ret = ((ThreadedDriver*)devicep)->MainSetup();
+  int ret = tdriver.MainSetup();
   // Run the overloaded Main() in the subclassed device.
   if (ret == 0)
   {
-    ((ThreadedDriver*)devicep)->SetupSuccessful = true;
-    ((ThreadedDriver*)devicep)->Main();
+    tdriver.SetupSuccessful = true;
+    tdriver.Main();
   }
   else
   {


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to