Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

asyncdns.cpp

00001 /*
00002   Copyright (c) 2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 #include "asyncdns.h"
00014 #include "asyncdnshandler.h"
00015 #include "dns.h"
00016 #include "mutexguard.h"
00017 #include "thread.h"
00018 #include "util.h"
00019 
00020 namespace  gloox
00021 {
00022 
00023 #if ( defined( _WIN32 ) && !defined( __SYMBIAN32__ ) ) || defined( HAVE_PTHREAD )
00024 
00025   class AsyncDNSWorker : public util::Thread
00026   {
00027     public:
00036       AsyncDNSWorker( AsyncDNSHandler* adh, const std::string& service, const std::string& proto,
00037                       const std::string& domain, const LogSink& logInstance );
00038 
00046       AsyncDNSWorker( AsyncDNSHandler* adh, const std::string& host,
00047                       const LogSink& logInstance );
00048 
00057       AsyncDNSWorker( AsyncDNSHandler* adh, const std::string& host, int port,
00058                       const LogSink& logInstance );
00059 
00063       virtual ~AsyncDNSWorker();
00064 
00065     protected:
00066       // reimplemented from Thread
00067       virtual void run();
00068 
00069     private:
00070       enum JobType
00071       {
00072         Resolve,
00073         ConnectResolve,
00074         Connect
00075       };
00076 
00077       void* m_context;
00078       AsyncDNSHandler* m_adh;
00079       std::string m_service;
00080       std::string m_proto;
00081       std::string m_domain;
00082       std::string m_host;
00083       int m_port;
00084       const LogSink& m_logInstance;
00085 
00086       JobType m_type;
00087 
00088   };
00089 
00090   AsyncDNSWorker::AsyncDNSWorker( AsyncDNSHandler* adh, const std::string& service,
00091                                   const std::string& proto, const std::string& domain,
00092                                   const LogSink& logInstance )
00093     : m_adh( adh ), m_service( service ), m_proto( proto ), m_domain( domain ), m_port( -1 ),
00094       m_logInstance( logInstance ), m_type( Resolve )
00095   {
00096   }
00097 
00098   AsyncDNSWorker::AsyncDNSWorker( AsyncDNSHandler* adh, const std::string& host,
00099                                   const LogSink& logInstance )
00100     : m_adh( adh ), m_host( host ), m_port( -1 ), m_logInstance( logInstance ),
00101       m_type( ConnectResolve )
00102   {
00103   }
00104 
00105   AsyncDNSWorker::AsyncDNSWorker( AsyncDNSHandler* adh, const std::string& host, int port,
00106                                   const LogSink& logInstance )
00107     : m_adh( adh ), m_host( host ), m_port( port ), m_logInstance( logInstance ),
00108       m_type( Connect )
00109   {
00110   }
00111 
00112   AsyncDNSWorker::~AsyncDNSWorker()
00113   {
00114   }
00115 
00116   void AsyncDNSWorker::run()
00117   {
00118     switch( m_type )
00119     {
00120       case Resolve:
00121       {
00122         const DNS::HostMap& hm = DNS::resolve( m_service, m_proto, m_domain, m_logInstance );
00123         m_adh->handleAsyncResolveResult( hm, this );
00124         break;
00125       }
00126       case ConnectResolve:
00127       {
00128         int fd = DNS::connect( m_host, m_logInstance );
00129         m_adh->handleAsyncConnectResult( fd, this );
00130         break;
00131       }
00132       case Connect:
00133       {
00134         int fd = DNS::connect( m_host, m_port, m_logInstance );
00135         m_adh->handleAsyncConnectResult( fd, this );
00136         break;
00137       }
00138     }
00139   }
00140   // ---- ~AsyncDNSWorker ----
00141 
00142   // ---- AsyncDNS ----
00143   AsyncDNS::AsyncDNS()
00144   {
00145   }
00146 
00147   AsyncDNS::~AsyncDNS()
00148   {
00149     WorkerMap::iterator it = m_workers.begin();
00150     for( ; it != m_workers.end(); ++it )
00151     {
00152       delete (*it).first;
00153     }
00154 
00155     util::clearList( m_obsoleteWorkers );
00156   }
00157 
00158   void AsyncDNS::resolve( AsyncDNSHandler* adh, const std::string& service, const std::string& proto,
00159                           const std::string& domain, const LogSink& logInstance, void* context )
00160   {
00161     m_obsoleteWorkerMutex.lock();
00162     util::clearList( m_obsoleteWorkers );
00163     m_obsoleteWorkerMutex.unlock();
00164 
00165     AsyncDNSWorker* adw = new AsyncDNSWorker( this, service, proto, domain, logInstance );
00166     AsyncContext ac( adh, context );
00167     m_workerMutex.lock();
00168     m_workers.insert( std::make_pair( adw, ac ) );
00169     m_workerMutex.unlock();
00170     adw->start();
00171   }
00172 
00173   void AsyncDNS::connect( AsyncDNSHandler* adh, const std::string& host,
00174                            const LogSink& logInstance, void* context )
00175   {
00176     m_obsoleteWorkerMutex.lock();
00177     util::clearList( m_obsoleteWorkers );
00178     m_obsoleteWorkerMutex.unlock();
00179 
00180     AsyncDNSWorker* adw = new AsyncDNSWorker( this, host, logInstance );
00181     AsyncContext ac( adh, context );
00182     m_workerMutex.lock();
00183     m_workers.insert( std::make_pair( adw, ac ) );
00184     m_workerMutex.unlock();
00185     adw->start();
00186   }
00187 
00188   void AsyncDNS::connect( AsyncDNSHandler* adh, const std::string& host, int port,
00189                            const LogSink& logInstance, void* context )
00190   {
00191     m_obsoleteWorkerMutex.lock();
00192     util::clearList( m_obsoleteWorkers );
00193     m_obsoleteWorkerMutex.unlock();
00194 
00195     AsyncDNSWorker* adw = new AsyncDNSWorker( this, host, port, logInstance );
00196     AsyncContext ac( adh, context );
00197     m_workerMutex.lock();
00198     m_workers.insert( std::make_pair( adw, ac ) );
00199     m_workerMutex.unlock();
00200     adw->start();
00201   }
00202 
00203   void AsyncDNS::handleAsyncResolveResult( const DNS::HostMap& hosts, void* context )
00204   {
00205     AsyncDNSWorker* adw = static_cast<AsyncDNSWorker*>( context );
00206 
00207     util::MutexGuard mg( m_workerMutex );
00208     WorkerMap::iterator it = m_workers.begin();
00209     for( ; it != m_workers.end(); ++it )
00210     {
00211       if( (*it).first == adw )
00212       {
00213         AsyncDNSHandler* adh = (*it).second.handler;
00214         void* ctx = (*it).second.context;
00215         m_obsoleteWorkerMutex.lock();
00216         m_obsoleteWorkers.push_back( (*it).first );
00217         m_obsoleteWorkerMutex.unlock();
00218         m_workers.erase( it );
00219         adh->handleAsyncResolveResult( hosts, ctx );
00220         return;
00221       }
00222     }
00223   }
00224 
00225   void AsyncDNS::handleAsyncConnectResult( int fd, void* context )
00226   {
00227     AsyncDNSWorker* adw = static_cast<AsyncDNSWorker*>( context );
00228 
00229     util::MutexGuard mg( m_workerMutex );
00230     WorkerMap::iterator it = m_workers.begin();
00231     for( ; it != m_workers.end(); ++it )
00232     {
00233       if( (*it).first == adw )
00234       {
00235         AsyncDNSHandler* adh = (*it).second.handler;
00236         void* ctx = (*it).second.context;
00237         m_obsoleteWorkerMutex.lock();
00238         m_obsoleteWorkers.push_back( (*it).first );
00239         m_obsoleteWorkerMutex.unlock();
00240         m_workers.erase( it );
00241         adh->handleAsyncConnectResult( fd, ctx );
00242         return;
00243       }
00244     }
00245   }
00246 
00247 #else
00248 
00249 #endif // WANT_ASYNC_DNS
00250 
00251 }

Generated on Tue May 4 16:35:11 2010 for gloox by  doxygen 1.4.1