]> git.mxchange.org Git - flightgear.git/commitdiff
Add threading to metar data fetching where available.
authorehofman <ehofman>
Wed, 25 Feb 2004 15:31:01 +0000 (15:31 +0000)
committerehofman <ehofman>
Wed, 25 Feb 2004 15:31:01 +0000 (15:31 +0000)
src/Environment/environment_ctrl.cxx
src/Environment/environment_ctrl.hxx

index 953066034c6fd4fa6ad31ce76d1abeecc956a379..46278edc28699e74cc468a7a7430a8cfaa356c5a 100644 (file)
@@ -320,10 +320,19 @@ FGMetarEnvironmentCtrl::FGMetarEnvironmentCtrl ()
       update_interval_sec( 60.0 ),
       elapsed( 60.0 )
 {
+#ifdef ENABLE_THREADS
+    thread = new MetarThread(this);
+    thread->start();
+#endif // ENABLE_THREADS
 }
 
 FGMetarEnvironmentCtrl::~FGMetarEnvironmentCtrl ()
 {
+#ifdef ENABLE_THREADS
+   thread->cancel();
+   thread->join();
+#endif // ENABLE_THREADS
+
    delete env;
    env = NULL;
 }
@@ -411,9 +420,9 @@ FGMetarEnvironmentCtrl::reinit ()
 void
 FGMetarEnvironmentCtrl::update(double delta_time_sec)
 {
-    const SGPropertyNode *longitude
+    static const SGPropertyNode *longitude
         = fgGetNode( "/position/longitude-deg", true );
-    const SGPropertyNode *latitude
+    static const SGPropertyNode *latitude
         = fgGetNode( "/position/latitude-deg", true );
     elapsed += delta_time_sec;
     if ( elapsed > update_interval_sec ) {
@@ -434,6 +443,7 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
             globals->get_airports()->no_metar( a.id );
         }
     }
+
     env->update(delta_time_sec);
 }
 
@@ -462,7 +472,26 @@ FGMetarEnvironmentCtrl::fetch_data (const string &icao)
     station_elevation_ft = a.elevation;
 
     // fetch current metar data
-    SGMetar *m;
+    SGMetar *m = NULL;
+#ifdef ENABLE_THREADS
+
+    bool valid_data = false;
+    if (!metar_queue.empty())
+    {
+        m = metar_queue.pop();
+
+        if (m != NULL)
+            valid_data = true;
+    }
+
+    if ( valid_data == false ) {
+        mutex.lock();
+        metar_cond.signal();
+        mutex.unlock();
+
+        return false;
+    }
+#else
     try {
         m = new SGMetar( _icao.c_str() );
     } catch (const sg_io_exception& e) {
@@ -470,6 +499,7 @@ FGMetarEnvironmentCtrl::fetch_data (const string &icao)
                                       << e.getFormattedMessage().c_str() );
         return false;
     }
+#endif // ENABLE_THREADS
 
     d = m->getMinVisibility().getVisibility_m();
     d = (d != SGMetarNaN) ? d : 10000;
@@ -576,8 +606,61 @@ FGMetarEnvironmentCtrl::fetch_data (const string &icao)
 
     delete m;
 
+#ifdef ENABLE_THREADS
+    mutex.lock();
+    metar_cond.signal();
+    mutex.unlock();
+#endif // ENABLE_THREADS
+
     return true;
 }
 
+#ifdef ENABLE_THREADS
+/**
+ *
+ */
+void
+FGMetarEnvironmentCtrl::MetarThread::run()
+{
+    SGMetar *m = NULL;
+
+    // pthread_cleanup_push( metar_cleanup_handler, fetcher );
+    while ( true )
+    {
+        set_cancel( SGThread::CANCEL_DISABLE );
+        try
+        {
+            cout << "Fetching ..." << endl;
+            // if (m != NULL)  m = NULL;
+            m = new SGMetar( fetcher->_icao.c_str() );
+
+        } catch (const sg_io_exception& e) {
+            // SG_LOG( SG_GENERAL, SG_WARN, "Error fetching live weather data: "
+            //                             << e.getFormattedMessage().c_str() );
+            m = NULL;
+        }
+        set_cancel( SGThread::CANCEL_DEFERRED );
+
+        fetcher->metar_queue.push( m );
+
+        // Wait for the next frame signal before we fetch the next metar data
+        fetcher->mutex.lock();
+        fetcher->metar_cond.wait( fetcher->mutex );
+        fetcher->mutex.unlock();
+    }
+    // pthread_cleanup_pop(1);
+}
+
+/**
+ * Ensure mutex is unlocked.
+ */
+void
+metar_cleanup_handler( void* arg )
+{
+    FGMetarEnvironmentCtrl* fetcher = (FGMetarEnvironmentCtrl*) arg;
+    fetcher->mutex.unlock();
+}
+#endif // ENABLE_THREADS
+
 
 // end of environment_ctrl.cxx
index 61617a3fc3160b7a6d199c82ad26de36d3b7b4a8..5b48823ac4ed737dc4027f934d2185cbb48d6f05 100644 (file)
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/environment/metar.hxx>
 
+#ifdef ENABLE_THREADS
+# include <simgear/threads/SGThread.hxx>
+# include <simgear/threads/SGQueue.hxx>
+#endif
+
 #ifdef SG_HAVE_STD_INCLUDES
 #  include <cmath>
 #else
@@ -159,6 +164,58 @@ private:
     float elapsed;
     bool fetch_data (const string &icao);
     void update_env_config();
+
+private:
+
+#ifdef ENABLE_THREADS
+    /**
+     * FIFO queue which holds a pointer to the fetched metar data.
+     */
+    SGBlockingQueue< SGMetar * > metar_queue;
+
+    /**
+     * This class represents the thread of execution responsible for
+     * fetching the metar data.
+     */
+    class MetarThread : public SGThread
+    {
+    public:
+        MetarThread( FGMetarEnvironmentCtrl* f ) : fetcher(f) {}
+        ~MetarThread() {}
+
+        /**
+         * Reads the tile from disk.
+         */
+        void run();
+
+    private:
+        FGMetarEnvironmentCtrl *fetcher;
+
+    private:
+        // not implemented.
+        MetarThread();
+        MetarThread( const MetarThread& );
+        MetarThread& operator=( const MetarThread& );
+    };
+
+    friend class MetarThread;
+
+    /**
+     * Metar data fetching thread.
+     */
+    MetarThread* thread;
+
+    /**
+     * Lock and synchronize access to metar queue.
+     */
+    SGMutex mutex;
+    SGPthreadCond metar_cond;
+
+    /**
+     * Thread cleanup handler.
+     */
+    friend void metar_cleanup_handler( void* );
+#endif // ENABLE_THREADS
 };
 
 #endif // _ENVIRONMENT_CTRL_HXX