nsProxyEventObject.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "prprf.h"
#include "prmem.h"
#include "nscore.h"
#include "nsProxyEvent.h"
#include "nsIProxyObjectManager.h"
#include "nsProxyEventPrivate.h"
#include "nsHashtable.h"
#include "nsIInterfaceInfoManager.h"
#include "xptcall.h"
#include "nsAutoLock.h"
////////////////////////////////////////////////////////////////////////////////
class nsProxyEventKey : public nsHashKey
{
public:
}
return NS_PTR_TO_INT32(mRootObjectKey) ^
}
}
}
protected:
void* mRootObjectKey;
void* mDestQueueKey;
};
////////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG_xpcom_proxy
static PRUint32 totalProxyObjects = 0;
static PRUint32 outstandingProxyObjects = 0;
void
{
{
mon = PR_NewMonitor();
}
if (message)
{
printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-\n");
{
}
{
}
}
char* name;
if(name)
delete iid;
if(mNext)
{
if(isRoot)
{
printf("Additional wrappers for this object...\n");
}
}
printf("[proxyobjects] %d total used in system, %d outstading\n", totalProxyObjects, outstandingProxyObjects);
if (message)
printf("-=-=-=-=-=-=-=-=-=-=-=-=-\n");
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// nsProxyEventObject
//
//////////////////////////////////////////////////////////////////////////////////////////////////
{
if (!aObj)
return nsnull;
//
// make sure that the object pass in is not a proxy...
// if the object *is* a proxy, then be nice and build the proxy
// for the real object...
//
if (NS_SUCCEEDED(rv)) {
//
// ATTENTION!!!!
//
// If you are hitting any of the assertions in this block of code,
// please contact dougt@netscape.com.
//
// if you hit this assertion, you might want to check out how
// you are using proxies. You shouldn't need to be creating
// a proxy from a proxy. -- dougt@netscape.com
NS_ASSERTION(0, "Someone is building a proxy from a proxy");
if (!identificationObject) {
return nsnull;
}
// someone is asking us to create a proxy for a proxy. Lets get
// the real object and build aproxy for that!
if (!rawObject) {
return nsnull;
}
}
//
// Get the root nsISupports of the |real| object.
//
return nsnull;
}
// Get the root nsISupports of the event queue... This is used later,
// as part of the hashtable key...
return nsnull;
}
//
// Enter the proxy object creation lock.
//
// This lock protects thev linked list which chains proxies together
// (ie. mRoot and mNext) and ensures that there is no hashtable contention
// between the time that a proxy is looked up (and not found) in the
// hashtable and then added...
//
if (!manager) {
return nsnull;
}
// Get the hash table containing root proxy objects...
if (!realToProxyMap) {
return nsnull;
}
// Now, lookup the root nsISupports of the raw object in the hashtable
// The key consists of 3 pieces of information:
// - root nsISupports of the raw object
// - event queue of the current thread
// - type of proxy being constructed...
//
// find in our hash table
if(rootProxy) {
//
// At least one proxy has already been created for this raw object...
//
// Look for the specific interface proxy in the list off of
// the root proxy...
//
if(peo) {
// An existing proxy is available... So use it.
return peo;
}
}
else {
// build the root proxy
if (!rootClazz) {
return nsnull;
}
nsnull);
if(!peo) {
// Ouch... Out of memory!
return nsnull;
}
// Add this root proxy into the hash table...
//
// Since the requested proxy is for the nsISupports interface of
// the raw object, use the new root proxy as the specific proxy
// too...
//
return peo;
}
// This assignment is an owning reference to the new ProxyEventObject.
// So, it will automatically get deleted if any subsequent early
// returns are taken...
}
//
// at this point we have a proxy for the root nsISupports (ie. rootProxy)
// but we need to build the specific proxy for this interface...
//
// Get a class for this IID.
if(!proxyClazz) {
return nsnull;
}
// Get the raw interface for this IID
return nsnull;
}
if (!peo) {
// Ouch... Out of memory!
return nsnull;
}
//
// Add the new specific proxy to the head of the list of proxies hanging
// off of the rootProxy...
//
return peo;
}
{
return this;
}
return this;
}
while(cur) {
return cur;
}
}
return nsnull;
}
{
NS_WARNING("This constructor should never be called");
}
{
#ifdef DEBUG_xpcom_proxy
DebugDump("Create", 0);
#endif
}
{
#ifdef DEBUG_xpcom_proxy
DebugDump("Delete", 0);
#endif
if (mRoot) {
//
// This proxy is not the root interface so it must be removed
// from the chain of proxies...
//
while(cur) {
break;
}
}
}
else {
//
// This proxy is for the root interface. Each proxy in the chain
// has a strong reference to the root... So, when its refcount goes
// to zero, it safe to remove it because no proxies are in its chain.
//
if (! nsProxyObjectManager::IsManagerShutdown()) {
if (realToProxyMap != nsnull) {
#ifdef DEBUG_dougt
void* value =
#endif
#ifdef DEBUG_dougt
#endif
}
}
}
// I am worried about ordering.
// do not remove assignments.
}
//
// nsISupports implementation...
//
nsProxyEventObject::Release(void)
{
//
// Be pessimistic about whether the manager or even the monitor exist...
// This is to protect against shutdown issues where a proxy object could
// be destroyed after (or while) the Proxy Manager is being destroyed...
//
// Decrement atomically - in case the Proxy Object Manager has already
// been deleted and the monitor is unavailable...
if (0 == count) {
//
// Remove the proxy from the hashtable (if necessary) or its
// proxy chain. This must be done inside of the proxy lock to
// prevent GetNewOrUsedProxy(...) from ressurecting it...
//
NS_DELETEXPCOM(this);
return 0;
}
return count;
}
{
{
return NS_OK;
}
}
//
// nsXPTCStubBase implementation...
//
{
if (!*info) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
const nsXPTMethodInfo* info,
{
if (mProxyObject) {
mClass->GetInterfaceInfo());
} else {
}
return rv;
}