bug# 49786 Weak ref cache commonly used protocol handlers. This will

eliminate about 1500 string copies and calls to ProgIDToClassID()
r=gagan,valeski
This commit is contained in:
dp%netscape.com 2000-08-22 06:16:50 +00:00
parent 7a4e9ced51
commit 69e5243d4f
2 changed files with 69 additions and 0 deletions

View File

@ -148,6 +148,54 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsIOService, nsIIOService);
#define MAX_NET_PROGID_LENGTH (MAX_SCHEME_LENGTH + NS_NETWORK_PROTOCOL_PROGID_PREFIX_LENGTH + 1)
NS_IMETHODIMP
nsIOService::CacheProtocolHandler(const char *scheme, nsIProtocolHandler *handler)
{
for (unsigned int i=0; i<NS_N(gScheme); i++)
{
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
{
nsresult rv;
NS_ASSERTION(!mWeakHandler[i], "Protocol handler already cached");
// Make sure the handler supports weak references.
nsCOMPtr<nsISupportsWeakReference> factoryPtr = do_QueryInterface(handler, &rv);
if (!factoryPtr)
{
// Dont cache handlers that dont support weak reference as
// there is real danger of a circular reference.
#ifdef DEBUG_dp
printf("DEBUG: %s protcol handler doesn't support weak ref. Not cached.\n", scheme);
#endif /* DEBUG_dp */
return NS_ERROR_FAILURE;
}
mWeakHandler[i] = getter_AddRefs(NS_GetWeakReference(handler));
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIOService::GetCachedProtocolHandler(const char *scheme, nsIProtocolHandler **result)
{
for (unsigned int i=0; i<NS_N(gScheme); i++)
{
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
if (mWeakHandler[i])
{
nsCOMPtr<nsIProtocolHandler> temp = do_QueryReferent(mWeakHandler[i]);
if (temp)
{
*result = temp.get();
NS_ADDREF(*result);
return NS_OK;
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
{
@ -162,6 +210,9 @@ nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
// scheme -> protocol handler mapping, avoiding the string manipulation
// and service manager stuff
rv = GetCachedProtocolHandler(scheme, result);
if (NS_SUCCEEDED(rv)) return NS_OK;
char buf[MAX_NET_PROGID_LENGTH];
nsCAutoString progID(NS_NETWORK_PROTOCOL_PROGID_PREFIX);
progID += scheme;
@ -172,6 +223,8 @@ nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
if (NS_FAILED(rv))
return NS_ERROR_UNKNOWN_PROTOCOL;
CacheProtocolHandler(scheme, *result);
return NS_OK;
}

View File

@ -30,6 +30,11 @@
#include "nsIDNSService.h"
#include "nsCOMPtr.h"
#include "nsURLHelper.h"
#include "nsWeakPtr.h"
#define NS_N(x) (sizeof(x)/sizeof(*x))
static const char *gScheme[] = {"chrome", "resource", "file", "http"};
class nsIOService : public nsIIOService
{
@ -50,11 +55,22 @@ public:
nsresult NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result, nsIProtocolHandler* *hdlrResult);
protected:
NS_METHOD GetCachedProtocolHandler(const char *scheme,
nsIProtocolHandler* *hdlrResult);
NS_METHOD CacheProtocolHandler(const char *scheme,
nsIProtocolHandler* hdlr);
protected:
PRBool mOffline;
nsCOMPtr<nsISocketTransportService> mSocketTransportService;
nsCOMPtr<nsIFileTransportService> mFileTransportService;
nsCOMPtr<nsIDNSService> mDNSService;
// Cached protocol handlers
nsWeakPtr mWeakHandler[NS_N(gScheme)];
};
#endif // nsIOService_h__