1
0
Fork 0

Add threading to metar data fetching where available.

This commit is contained in:
ehofman 2004-02-25 15:31:01 +00:00
parent 4fca15fa1d
commit bca8c29795
2 changed files with 143 additions and 3 deletions

View 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

View file

@ -27,6 +27,11 @@
#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