Follow-on fix for bug 457825. Use sheet principal for agent and user sheets. r=dbaron...
[wine-gecko.git] / netwerk / dns / src / nsHostResolver.h
blob054e317c41c65e70cd824a3282ed0d1e30216c74
1 /* vim:set ts=4 sw=4 sts=4 et cin: */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Mozilla.
17 * The Initial Developer of the Original Code is IBM Corporation.
18 * Portions created by IBM Corporation are Copyright (C) 2003
19 * IBM Corporation. All Rights Reserved.
21 * Contributor(s):
22 * IBM Corp.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsHostResolver_h__
39 #define nsHostResolver_h__
41 #include "nscore.h"
42 #include "pratom.h"
43 #include "prcvar.h"
44 #include "prclist.h"
45 #include "prnetdb.h"
46 #include "pldhash.h"
47 #include "nsISupportsImpl.h"
49 class nsHostResolver;
50 class nsHostRecord;
51 class nsResolveHostCallback;
53 /* XXX move this someplace more generic */
54 #define NS_DECL_REFCOUNTED_THREADSAFE(classname) \
55 private: \
56 nsAutoRefCnt _refc; \
57 public: \
58 PRInt32 AddRef() { \
59 PRInt32 n = PR_AtomicIncrement((PRInt32*)&_refc); \
60 NS_LOG_ADDREF(this, n, #classname, sizeof(classname)); \
61 return n; \
62 } \
63 PRInt32 Release() { \
64 PRInt32 n = PR_AtomicDecrement((PRInt32*)&_refc); \
65 NS_LOG_RELEASE(this, n, #classname); \
66 if (n == 0) \
67 delete this; \
68 return n; \
71 #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 3
72 #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
73 #define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
74 MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
76 struct nsHostKey
78 const char *host;
79 PRUint16 flags;
80 PRUint16 af;
83 /**
84 * nsHostRecord - ref counted object type stored in host resolver cache.
86 class nsHostRecord : public PRCList, public nsHostKey
88 public:
89 NS_DECL_REFCOUNTED_THREADSAFE(nsHostRecord)
91 /* instantiates a new host record */
92 static nsresult Create(const nsHostKey *key, nsHostRecord **record);
94 /* a fully resolved host record has either a non-null |addr_info| or |addr|
95 * field. if |addr_info| is null, it implies that the |host| is an IP
96 * address literal. in which case, |addr| contains the parsed address.
97 * otherwise, if |addr_info| is non-null, then it contains one or many
98 * IP addresses corresponding to the given host name. if both |addr_info|
99 * and |addr| are null, then the given host has not yet been fully resolved.
100 * |af| is the address family of the record we are querying for.
103 /* the lock protects |addr_info| and |addr_info_gencnt| because they
104 * are mutable and accessed by the resolver worker thread and the
105 * nsDNSService2 class. |addr| doesn't change after it has been
106 * assigned a value. only the resolver worker thread modifies
107 * nsHostRecord (and only in nsHostResolver::OnLookupComplete);
108 * the other threads just read it. therefore the resolver worker
109 * thread doesn't need to lock when reading |addr_info|.
111 PRLock *addr_info_lock;
112 int addr_info_gencnt; /* generation count of |addr_info| */
113 PRAddrInfo *addr_info;
114 PRNetAddr *addr;
115 PRBool negative; /* True if this record is a cache of a failed lookup.
116 Negative cache entries are valid just like any other
117 (though never for more than 60 seconds), but a use
118 of that negative entry forces an asynchronous refresh. */
120 PRUint32 expiration; /* measured in minutes since epoch */
122 PRBool HasResult() const { return addr_info || addr || negative; }
124 private:
125 friend class nsHostResolver;
127 PRCList callbacks; /* list of callbacks */
129 PRBool resolving; /* true if this record is being resolved, which means
130 * that it is either on the pending queue or owned by
131 * one of the worker threads. */
133 PRBool onQueue; /* true if pending and on the queue (not yet given to getaddrinfo())*/
136 ~nsHostRecord();
140 * ResolveHost callback object. It's PRCList members are used by
141 * the nsHostResolver and should not be used by anything else.
143 class NS_NO_VTABLE nsResolveHostCallback : public PRCList
145 public:
147 * OnLookupComplete
149 * this function is called to complete a host lookup initiated by
150 * nsHostResolver::ResolveHost. it may be invoked recursively from
151 * ResolveHost or on an unspecified background thread.
153 * NOTE: it is the responsibility of the implementor of this method
154 * to handle the callback in a thread safe manner.
156 * @param resolver
157 * nsHostResolver object associated with this result
158 * @param record
159 * the host record containing the results of the lookup
160 * @param status
161 * if successful, |record| contains non-null results
163 virtual void OnLookupComplete(nsHostResolver *resolver,
164 nsHostRecord *record,
165 nsresult status) = 0;
169 * nsHostResolverThreadInfo structures are passed to the resolver
170 * thread.
172 struct nsHostResolverThreadInfo
174 nsHostResolver *self;
175 PRBool onlyHighPriority;
179 * nsHostResolver - an asynchronous host name resolver.
181 class nsHostResolver
183 public:
185 * host resolver instances are reference counted.
187 NS_DECL_REFCOUNTED_THREADSAFE(nsHostResolver)
190 * creates an addref'd instance of a nsHostResolver object.
192 static nsresult Create(PRUint32 maxCacheEntries, // zero disables cache
193 PRUint32 maxCacheLifetime, // minutes
194 nsHostResolver **resolver);
197 * puts the resolver in the shutdown state, which will cause any pending
198 * callbacks to be detached. any future calls to ResolveHost will fail.
200 void Shutdown();
203 * resolve the given hostname asynchronously. the caller can synthesize
204 * a synchronous host lookup using a lock and a cvar. as noted above
205 * the callback will occur re-entrantly from an unspecified thread. the
206 * host lookup cannot be canceled (cancelation can be layered above this
207 * by having the callback implementation return without doing anything).
209 nsresult ResolveHost(const char *hostname,
210 PRUint16 flags,
211 PRUint16 af,
212 nsResolveHostCallback *callback);
215 * removes the specified callback from the nsHostRecord for the given
216 * hostname, flags, and address family. these parameters should correspond
217 * to the parameters passed to ResolveHost. this function executes the
218 * callback if the callback is still pending with the given status.
220 void DetachCallback(const char *hostname,
221 PRUint16 flags,
222 PRUint16 af,
223 nsResolveHostCallback *callback,
224 nsresult status);
227 * values for the flags parameter passed to ResolveHost and DetachCallback
228 * that may be bitwise OR'd together.
230 * NOTE: in this implementation, these flags correspond exactly in value
231 * to the flags defined on nsIDNSService.
233 enum {
234 RES_BYPASS_CACHE = 1 << 0,
235 RES_CANON_NAME = 1 << 1,
236 RES_PRIORITY_MEDIUM = 1 << 2,
237 RES_PRIORITY_LOW = 1 << 3
240 private:
241 nsHostResolver(PRUint32 maxCacheEntries=50, PRUint32 maxCacheLifetime=1);
242 ~nsHostResolver();
244 // nsHostResolverThreadInfo * is passed to the ThreadFunc
245 struct nsHostResolverThreadInfo mHighPriorityInfo, mAnyPriorityInfo;
247 nsresult Init();
248 nsresult IssueLookup(nsHostRecord *);
249 PRBool GetHostToLookup(nsHostRecord **m, struct nsHostResolverThreadInfo *aID);
250 void OnLookupComplete(nsHostRecord *, nsresult, PRAddrInfo *);
251 void DeQueue(PRCList &aQ, nsHostRecord **aResult);
252 void ClearPendingQueue(PRCList *aPendingQueue);
253 nsresult ConditionallyCreateThread(nsHostRecord *rec);
255 static void MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);
257 static void ThreadFunc(void *);
259 PRUint32 mMaxCacheEntries;
260 PRUint32 mMaxCacheLifetime;
261 PRLock *mLock;
262 PRCondVar *mIdleThreadCV; // non-null if idle thread
263 PRUint32 mNumIdleThreads;
264 PRUint32 mThreadCount;
265 PRUint32 mAnyPriorityThreadCount;
266 PLDHashTable mDB;
267 PRCList mHighQ;
268 PRCList mMediumQ;
269 PRCList mLowQ;
270 PRCList mEvictionQ;
271 PRUint32 mEvictionQSize;
272 PRUint32 mPendingCount;
273 PRTime mCreationTime;
274 PRBool mShutdown;
275 PRIntervalTime mLongIdleTimeout;
276 PRIntervalTime mShortIdleTimeout;
279 #endif // nsHostResolver_h__