Partially resolves bug 10733. XP_UNIX does not have an async DNS implementation. r=rpotts, sr=mscott.

This commit is contained in:
darin%netscape.com 2001-02-23 00:15:35 +00:00
Родитель 6ddb173736
Коммит 5f53dc2545
2 изменённых файлов: 205 добавлений и 26 удалений

Просмотреть файл

@ -26,7 +26,6 @@
#include "nsError.h"
#include "prnetdb.h"
#include "nsString.h"
//#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "netCore.h"
#include "nsAutoLock.h"
@ -38,8 +37,6 @@
#endif
#include "prsystem.h"
//static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
// Platform specific defines and includes
////////////////////////////////////////////////////////////////////////////////
@ -99,6 +96,7 @@ public:
, mStartTime(PR_IntervalNow())
#endif
{ NS_INIT_REFCNT(); }
virtual ~nsDNSRequest() {}
nsresult Init(nsDNSLookup* lookup,
@ -185,6 +183,14 @@ protected:
HANDLE mLookupHandle;
PRUint32 mMsgID;
#endif
#if defined(XP_UNIX)
nsresult DoSyncLookup();
nsresult AppendLookup(nsDNSLookup *lookup);
nsresult GetNextLookup(nsDNSLookup **lookup);
nsresult ClearNextLookup();
nsDNSLookup *mNextLookup;
#endif
};
@ -363,6 +369,9 @@ nsDNSLookup::nsDNSLookup()
mStatus(NS_OK),
mComplete(PR_FALSE),
mExpires(0)
#if defined(XP_UNIX)
, mNextLookup(nsnull)
#endif
{
NS_INIT_REFCNT();
MOZ_COUNT_CTOR(nsDNSLookup);
@ -405,7 +414,6 @@ nsDNSLookup::Reset(void)
mComplete = PR_FALSE;
mStatus = NS_OK;
mExpires = LL_ZERO;
// fprintf(stderr, "DNS reset for %s\n", mHostName);
}
nsDNSLookup::~nsDNSLookup(void)
@ -414,6 +422,11 @@ nsDNSLookup::~nsDNSLookup(void)
if (mHostName)
nsCRT::free(mHostName);
#if defined(XP_UNIX)
if (mNextLookup)
NS_RELEASE(mNextLookup);
#endif
}
#if defined(XP_MAC)
@ -590,7 +603,14 @@ nsDNSLookup::InitiateLookup(void)
}
#endif /* XP_WIN */
#if defined(XP_UNIX) || defined(XP_BEOS)
#if defined(XP_UNIX)
//
// Add to lookup queue
//
nsDNSService::gService->EnqueueLookup(this);
#endif
#if defined(XP_BEOS)
// temporary SYNC version
status = PR_GetIPNodeByName(mHostName,
PR_AF_INET6,
@ -688,7 +708,6 @@ nsDNSLookup::Resume(nsDNSRequest* req)
PRUint32 reqCount;
if (mComplete && !IsExpired()) {
// fprintf(stderr, "\nDNS cache hit for %s\n", mHostName);
rv = req->FireStop(mStatus);
return rv;
}
@ -706,12 +725,8 @@ nsDNSLookup::Resume(nsDNSRequest* req)
if (reqCount == 1) {
// if this was the first request, then we need to kick off
// the lookup
// fprintf(stderr, "\nDNS cache miss for %s\n", mHostName);
rv = InitiateLookup();
}
else {
// fprintf(stderr, "DNS consolidating lookup for %s\n", mHostName);
}
return rv;
}
@ -726,9 +741,9 @@ nsDnsServiceNotifierRoutine(void * contextPtr, OTEventCode code,
OTResult result, void * cookie)
{
OSStatus errOT;
nsDNSService * dnsService = (nsDNSService *)contextPtr;
nsDNSLookup * dnsLookup = ((nsInetHostInfo *)cookie)->lookup;
PRThread * thread;
nsDNSService * dnsService = (nsDNSService *)contextPtr;
nsDNSLookup * dnsLookup = ((nsInetHostInfo *)cookie)->lookup;
PRThread * thread;
dnsService->mThread->GetPRThread(&thread);
@ -837,7 +852,113 @@ nsDNSEventProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
#endif /* XP_WIN */
#ifdef XP_UNIX
#if defined(XP_UNIX)
nsresult
nsDNSLookup::DoSyncLookup()
{
nsresult status, rv = NS_OK;
//
// Synchronous DNS lookup
//
status = PR_GetIPNodeByName(mHostName,
PR_AF_INET6,
PR_AI_DEFAULT,
mHostEntry.buffer,
PR_NETDB_BUF_SIZE,
&(mHostEntry.hostEnt));
if (PR_SUCCESS != status)
rv = NS_ERROR_UNKNOWN_HOST;
rv = CompleteLookup(rv);
// XXX remove from hashtable and release - for now
nsCStringKey key(mHostName);
nsDNSService::gService->mLookups.Remove(&key);
return rv;
}
nsresult
nsDNSLookup::AppendLookup(nsDNSLookup *lookup)
{
NS_ENSURE_ARG_POINTER(lookup);
if (mNextLookup)
return mNextLookup->AppendLookup(lookup);
else {
mNextLookup = lookup;
NS_ADDREF(mNextLookup);
return NS_OK;
}
}
nsresult
nsDNSLookup::GetNextLookup(nsDNSLookup **lookup)
{
NS_ENSURE_ARG_POINTER(lookup);
if (mNextLookup) {
*lookup = mNextLookup;
NS_ADDREF(*lookup);
}
else
*lookup = nsnull;
return NS_OK;
}
nsresult
nsDNSLookup::ClearNextLookup()
{
if (mNextLookup) {
NS_RELEASE(mNextLookup);
mNextLookup = nsnull;
}
return NS_OK;
}
nsresult
nsDNSService::EnqueueLookup(nsDNSLookup *lookup)
{
NS_ENSURE_ARG_POINTER(lookup);
nsAutoMonitor mon(mLookupQMon);
// Place the lookup at the end of the queue.
if (mLookupQ)
mLookupQ->AppendLookup(lookup);
else {
mLookupQ = lookup;
NS_ADDREF(lookup);
}
// Notify the worker thread that a request has been queued.
mon.Notify();
return NS_OK;
}
nsresult
nsDNSService::DequeueLookup(nsDNSLookup **lookup)
{
NS_ENSURE_ARG_POINTER(lookup);
nsAutoMonitor mon(mLookupQMon);
// Wait for notification of a queued request.
if (!mLookupQ)
mon.Wait();
// Got a request!!
if (mLookupQ) {
// Remove the first lookup from the queue.
*lookup = mLookupQ;
mLookupQ->GetNextLookup(&mLookupQ);
(*lookup)->ClearNextLookup();
}
else
*lookup = nsnull;
return NS_OK;
}
#endif /* XP_UNIX */
@ -849,6 +970,9 @@ nsDNSService::nsDNSService()
: mState(NS_OK),
mMonitor(nsnull),
mLookups(64)
#if defined(XP_UNIX)
, mLookupQ(nsnull)
#endif
#ifdef DNS_TIMING
,
mCount(0),
@ -928,7 +1052,13 @@ nsDNSService::Init()
nsAutoMonitor mon(mMonitor);
#endif
#if defined(XP_MAC) || defined(XP_WIN)
#if defined(XP_UNIX)
mLookupQMon = nsAutoMonitor::NewMonitor("nsDNSService::mLookupQ");
if (!mLookupQMon)
return NS_ERROR_OUT_OF_MEMORY;
#endif
#if defined(XP_MAC) || defined(XP_WIN) || defined(XP_UNIX)
// create DNS thread
NS_ASSERTION(mThread == nsnull, "nsDNSService not shut down");
rv = NS_NewThread(getter_AddRefs(mThread), this, 0, PR_JOINABLE_THREAD);
@ -984,6 +1114,11 @@ nsDNSService::~nsDNSService()
NS_ASSERTION(mThread == nsnull, "DNS shutdown failed");
NS_ASSERTION(mLookups.Count() == 0, "didn't clean up lookups");
#if defined(XP_UNIX)
NS_ASSERTION(mLookupQ == nsnull, "DNS lookup queue not cleared");
NS_ASSERTION(mLookupQMon == nsnull, "DNS lookup queue monitor not destroyed");
#endif
if (mMonitor) {
nsAutoMonitor::DestroyMonitor(mMonitor);
}
@ -1119,6 +1254,25 @@ nsDNSService::Run(void)
}
#endif /* XP_MAC */
#if defined(XP_UNIX)
while (1) {
nsDNSLookup *lookup = nsnull;
rv = DequeueLookup(&lookup);
if (NS_FAILED(rv)) return rv;
if (lookup) {
//
// Got a request!!
//
lookup->DoSyncLookup();
NS_RELEASE(lookup);
} else
// Woken up without a request --> shutdown
break;
}
#endif
return rv;
}
@ -1135,14 +1289,6 @@ nsDNSService::Lookup(const char* hostName,
nsresult rv;
nsDNSRequest* req;
/* Hmmm... this check not necessary
NS_WITH_SERVICE(nsIIOService, ios, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
PRBool offline;
rv = ios->GetOffline(&offline);
if (NS_FAILED(rv)) return rv;
if (offline) return NS_ERROR_OFFLINE;
*/
if (!mMonitor)
return NS_ERROR_OFFLINE;
@ -1154,7 +1300,7 @@ nsDNSService::Lookup(const char* hostName,
}
}
#if !defined(XP_UNIX) && !defined(XP_OS2) && !defined(XP_BEOS)
#if !defined(XP_OS2) && !defined(XP_BEOS)
if (mThread == nsnull)
return NS_ERROR_OFFLINE;
#endif
@ -1356,7 +1502,7 @@ nsDNSService::Shutdown()
{
nsresult rv = NS_OK;
#if !defined(XP_UNIX) && !defined(XP_OS2) && !defined(XP_BEOS)
#if !defined(XP_OS2) && !defined(XP_BEOS)
if (mThread == nsnull) return rv;
#endif
@ -1391,7 +1537,25 @@ nsDNSService::Shutdown()
rv = mThread->Join();
#elif defined(XP_UNIX)
// XXXX - ?
{
//
// Clear the lookup queue and wake up the worker thread.
//
nsAutoMonitor mon2(mLookupQMon);
if (mLookupQ) {
mLookupQ->ClearNextLookup();
NS_RELEASE(mLookupQ);
mLookupQ = nsnull;
}
mon2.Notify();
}
// Wait for the worker thread to finish.
rv = mThread->Join();
if (mLookupQMon) {
nsAutoMonitor::DestroyMonitor(mLookupQMon);
mLookupQMon = nsnull;
}
#endif
}

Просмотреть файл

@ -98,6 +98,21 @@ protected:
PRUint32 mMsgIDBitVector[4];
#endif /* XP_WIN */
#if defined(XP_UNIX)
// The lookup queue: a linked list of lookups
nsDNSLookup *mLookupQ;
// The DNS thread waits on this monitor for lookups to process.
PRMonitor *mLookupQMon;
// Puts a lookup on the queue and signals the DNS thread.
nsresult EnqueueLookup(nsDNSLookup *);
// Called by the DNS thread to get the next lookup to process.
// Blocks until a lookup is available.
nsresult DequeueLookup(nsDNSLookup **);
#endif
#ifdef DNS_TIMING
double mCount;
double mTimes;