Back to index

lightning-sunbird  0.9+nobinonly
nsHostResolver.h
Go to the documentation of this file.
00001 /* vim:set ts=4 sw=4 sts=4 et cin: */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla.
00016  *
00017  * The Initial Developer of the Original Code is IBM Corporation.
00018  * Portions created by IBM Corporation are Copyright (C) 2003
00019  * IBM Corporation. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   IBM Corp.
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsHostResolver_h__
00039 #define nsHostResolver_h__
00040 
00041 #include "nscore.h"
00042 #include "pratom.h"
00043 #include "prcvar.h"
00044 #include "prclist.h"
00045 #include "prnetdb.h"
00046 #include "pldhash.h"
00047 #include "nsISupportsImpl.h"
00048 
00049 class nsHostResolver;
00050 class nsHostRecord;
00051 class nsResolveHostCallback;
00052 
00053 /* XXX move this someplace more generic */
00054 #define NS_DECL_REFCOUNTED_THREADSAFE                     \
00055   private:                                                \
00056     nsAutoRefCnt _refc;                                   \
00057   public:                                                 \
00058     PRInt32 AddRef() {                                    \
00059         return PR_AtomicIncrement((PRInt32*)&_refc);      \
00060     }                                                     \
00061     PRInt32 Release() {                                   \
00062         PRInt32 n = PR_AtomicDecrement((PRInt32*)&_refc); \
00063         if (n == 0)                                       \
00064             delete this;                                  \
00065         return n;                                         \
00066     }
00067 
00068 struct nsHostKey
00069 {
00070     const char *host;
00071     PRUint16    flags;
00072     PRUint16    af;
00073 };
00074 
00078 class nsHostRecord : public PRCList, public nsHostKey
00079 {
00080 public:
00081     NS_DECL_REFCOUNTED_THREADSAFE
00082 
00083     /* instantiates a new host record */
00084     static nsresult Create(const nsHostKey *key, nsHostRecord **record);
00085 
00086     /* a fully resolved host record has either a non-null |addr_info| or |addr|
00087      * field.  if |addr_info| is null, it implies that the |host| is an IP
00088      * address literal.  in which case, |addr| contains the parsed address.
00089      * otherwise, if |addr_info| is non-null, then it contains one or many
00090      * IP addresses corresponding to the given host name.  if both |addr_info|
00091      * and |addr| are null, then the given host has not yet been fully resolved.
00092      * |af| is the address family of the record we are querying for.
00093      */
00094 
00095     PRAddrInfo  *addr_info;
00096     PRNetAddr   *addr;
00097     PRUint32     expiration; /* measured in minutes since epoch */
00098 
00099     PRBool HasResult() const { return (addr_info || addr) != nsnull; }
00100 
00101 private:
00102     friend class nsHostResolver;
00103 
00104     PRCList callbacks; /* list of callbacks */
00105 
00106     PRBool  resolving; /* true if this record is being resolved, which means
00107                         * that it is either on the pending queue or owned by
00108                         * one of the worker threads. */ 
00109 
00110    ~nsHostRecord();
00111 };
00112 
00117 class NS_NO_VTABLE nsResolveHostCallback : public PRCList
00118 {
00119 public:
00137     virtual void OnLookupComplete(nsHostResolver *resolver,
00138                                   nsHostRecord   *record,
00139                                   nsresult        status) = 0;
00140 };
00141 
00145 class nsHostResolver
00146 {
00147 public:
00151     NS_DECL_REFCOUNTED_THREADSAFE
00152 
00156     static nsresult Create(PRUint32         maxCacheEntries,  // zero disables cache
00157                            PRUint32         maxCacheLifetime, // minutes
00158                            nsHostResolver **resolver);
00159     
00164     void Shutdown();
00165 
00173     nsresult ResolveHost(const char            *hostname,
00174                          PRUint16               flags,
00175                          PRUint16               af,
00176                          nsResolveHostCallback *callback);
00177 
00184     void DetachCallback(const char            *hostname,
00185                         PRUint16               flags,
00186                         PRUint16               af,
00187                         nsResolveHostCallback *callback,
00188                         nsresult               status);
00189 
00197     enum {
00198         RES_BYPASS_CACHE = 1 << 0,
00199         RES_CANON_NAME   = 1 << 1
00200     };
00201 
00202 private:
00203     nsHostResolver(PRUint32 maxCacheEntries=50, PRUint32 maxCacheLifetime=1);
00204    ~nsHostResolver();
00205 
00206     nsresult Init();
00207     nsresult IssueLookup(nsHostRecord *);
00208     PRBool   GetHostToLookup(nsHostRecord **);
00209     void     OnLookupComplete(nsHostRecord *, nsresult, PRAddrInfo *);
00210 
00211     PR_STATIC_CALLBACK(void) ThreadFunc(void *);
00212 
00213     PRUint32      mMaxCacheEntries;
00214     PRUint32      mMaxCacheLifetime;
00215     PRLock       *mLock;
00216     PRCondVar    *mIdleThreadCV; // non-null if idle thread
00217     PRBool        mHaveIdleThread;
00218     PRUint32      mThreadCount;
00219     PLDHashTable  mDB;
00220     PRCList       mPendingQ;
00221     PRCList       mEvictionQ;
00222     PRUint32      mEvictionQSize;
00223     PRTime        mCreationTime;
00224     PRBool        mShutdown;
00225 };
00226 
00227 #endif // nsHostResolver_h__