Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions
nsProxyEventObject Class Reference

#include <nsProxyEventPrivate.h>

Collaboration diagram for nsProxyEventObject:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_IMETHOD GetInterfaceInfo (nsIInterfaceInfo **info)
NS_IMETHOD CallMethod (PRUint16 methodIndex, const nsXPTMethodInfo *info, nsXPTCMiniVariant *params)
nsProxyEventClassGetClass () const
nsIEventQueueGetQueue () const
nsISupports * GetRealObject () const
PRInt32 GetProxyType () const
 nsProxyEventObject ()
 nsProxyEventObject (nsIEventQueue *destQueue, PRInt32 proxyType, nsISupports *aObj, nsProxyEventClass *aClass, nsProxyEventObject *root, nsIEventQueueService *eventQService)
nsProxyEventObjectLockedFind (REFNSIID aIID)

Static Public Member Functions

static NS_DECL_ISUPPORTS
nsProxyEventObject
GetNewOrUsedProxy (nsIEventQueue *destQueue, PRInt32 proxyType, nsISupports *aObj, REFNSIID aIID)

Protected Member Functions

void LockedRemoveProxy ()

Protected Attributes

nsCOMPtr< nsProxyEventClassmClass
nsRefPtr< nsProxyObjectmProxyObject
nsProxyEventObjectmRoot
nsProxyEventObjectmNext

Private Member Functions

 ~nsProxyEventObject ()

Detailed Description

Definition at line 107 of file nsProxyEventPrivate.h.


Constructor & Destructor Documentation

Definition at line 399 of file nsProxyEventObject.cpp.

: mNext(nsnull)
{
     NS_WARNING("This constructor should never be called");
}

Here is the caller graph for this function:

nsProxyEventObject::nsProxyEventObject ( nsIEventQueue destQueue,
PRInt32  proxyType,
nsISupports *  aObj,
nsProxyEventClass aClass,
nsProxyEventObject root,
nsIEventQueueService eventQService 
)

Definition at line 405 of file nsProxyEventObject.cpp.

    : mClass(aClass),
      mRoot(root),
      mNext(nsnull)
{
    NS_IF_ADDREF(mRoot);

    mProxyObject = new nsProxyObject(destQueue, proxyType, aObj, eventQService);

#ifdef DEBUG_xpcom_proxy
    DebugDump("Create", 0);
#endif
}

Here is the call graph for this function:

Definition at line 424 of file nsProxyEventObject.cpp.

{
#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...
        //
        nsProxyEventObject* cur = mRoot;
        while(cur) {
            if(cur->mNext == this) {
                cur->mNext = mNext;
                mNext = nsnull;
                break;
            }
            cur = cur->mNext;
        }
        NS_ASSERTION(cur, "failed to find wrapper in its own chain");
    }
    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()) {
            nsProxyObjectManager* manager = nsProxyObjectManager::GetInstance();
            nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap();

            NS_ASSERTION(!mNext, "There are still proxies in the chain!");

            if (realToProxyMap != nsnull) {
                nsCOMPtr<nsISupports> rootObject = do_QueryInterface(mProxyObject->mRealObject);
                nsCOMPtr<nsISupports> rootQueue = do_QueryInterface(mProxyObject->mDestQueue);
                nsProxyEventKey key(rootObject, rootQueue, mProxyObject->mProxyType);
#ifdef DEBUG_dougt
                void* value =
#endif
                    realToProxyMap->Remove(&key);
#ifdef DEBUG_dougt
                NS_ASSERTION(value, "failed to remove from realToProxyMap");
#endif
            }
        }
    }

    // I am worried about ordering.
    // do not remove assignments.
    mProxyObject = nsnull;
    mClass       = nsnull;
    NS_IF_RELEASE(mRoot);
}

Here is the call graph for this function:


Member Function Documentation

Definition at line 549 of file nsProxyEventObject.cpp.

{
    nsresult rv;

    if (mProxyObject) {
        rv = mProxyObject->Post(methodIndex,
                                (nsXPTMethodInfo*)info,
                                params,
                                mClass->GetInterfaceInfo());
    } else {
        rv = NS_ERROR_NULL_POINTER;
    }

    return rv;
}

Definition at line 127 of file nsProxyEventPrivate.h.

{ return mClass; }

Here is the caller graph for this function:

Definition at line 533 of file nsProxyEventObject.cpp.

{
    NS_ENSURE_ARG_POINTER(info);

    *info = mClass->GetInterfaceInfo();

    NS_ASSERTION(*info, "proxy class without interface");
    if (!*info) {
        return NS_ERROR_UNEXPECTED;
    }

    NS_ADDREF(*info);
    return NS_OK;
}

Here is the call graph for this function:

nsProxyEventObject * nsProxyEventObject::GetNewOrUsedProxy ( nsIEventQueue destQueue,
PRInt32  proxyType,
nsISupports *  aObj,
REFNSIID  aIID 
) [static]

Definition at line 170 of file nsProxyEventObject.cpp.

{
    nsresult rv;

    if (!aObj)
        return nsnull;

    nsISupports* rawObject = aObj;

    //
    // 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...
    //
    nsCOMPtr<nsProxyEventObject> identificationObject;

    rv = rawObject->QueryInterface(kProxyObject_Identity_Class_IID,
                                   getter_AddRefs(identificationObject));
    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");
        
        NS_ASSERTION(identificationObject, "where did my identification object go!");
        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!
        rawObject = identificationObject->GetRealObject();
        
        NS_ASSERTION(rawObject, "where did my real object go!");
        if (!rawObject) {
            return nsnull;
        }
    }

    //
    // Get the root nsISupports of the |real| object.
    //
    nsCOMPtr<nsISupports> rootObject;

    rootObject = do_QueryInterface(rawObject, &rv);
    if (NS_FAILED(rv) || !rootObject) {
        NS_ASSERTION(NS_FAILED(rv), "where did my root object go!");
        return nsnull;
    }

    // Get the root nsISupports of the event queue...  This is used later,
    // as part of the hashtable key...
    nsCOMPtr<nsISupports> destQRoot = do_QueryInterface(destQueue, &rv);
    if (NS_FAILED(rv) || !destQRoot) {
        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...
    //
    nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance();
    if (!manager) {
        return nsnull;
    }

    nsCOMPtr<nsIEventQueueService> eventQService(do_GetService(kEventQueueServiceCID, &rv));
    if (NS_FAILED(rv))
        return nsnull;
    
    nsAutoMonitor mon(manager->GetMonitor());

    // Get the hash table containing root proxy objects...
    nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap();
    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...
    //
    nsProxyEventKey rootkey(rootObject.get(), destQRoot.get(), proxyType);

    nsCOMPtr<nsProxyEventObject> rootProxy;
    nsCOMPtr<nsProxyEventObject> proxy;
    nsProxyEventObject* peo;

    // find in our hash table 
    rootProxy = (nsProxyEventObject*) realToProxyMap->Get(&rootkey);

    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...
        //
        peo = rootProxy->LockedFind(aIID);

        if(peo) {
            // An existing proxy is available... So use it.
            NS_ADDREF(peo);
            return peo;  
        }
    }
    else {
        // build the root proxy
        nsCOMPtr<nsProxyEventClass> rootClazz;

        rootClazz = dont_AddRef(nsProxyEventClass::GetNewOrUsedClass(
                                NS_GET_IID(nsISupports)));
        if (!rootClazz) {
            return nsnull;
        }

        peo = new nsProxyEventObject(destQueue, 
                                     proxyType, 
                                     rootObject, 
                                     rootClazz, 
                                     nsnull,
                                     eventQService);
        if(!peo) {
            // Ouch... Out of memory!
            return nsnull;
        }

        // Add this root proxy into the hash table...
        realToProxyMap->Put(&rootkey, peo);

        if(aIID.Equals(NS_GET_IID(nsISupports))) {
            //
            // Since the requested proxy is for the nsISupports interface of
            // the raw object, use the new root proxy as the specific proxy
            // too...
            //
            NS_ADDREF(peo);
            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...
        rootProxy = do_QueryInterface(peo);
    }

    //
    // at this point we have a proxy for the root nsISupports (ie. rootProxy)
    // but we need to build the specific proxy for this interface...
    //
    NS_ASSERTION(rootProxy, "What happened to the root proxy!");

    // Get a class for this IID.
    nsCOMPtr<nsProxyEventClass> proxyClazz;
        
    proxyClazz = dont_AddRef(nsProxyEventClass::GetNewOrUsedClass(aIID));
    if(!proxyClazz) {
        return nsnull;
    }

    // Get the raw interface for this IID
    nsCOMPtr<nsISupports> rawInterface;

    rv = rawObject->QueryInterface(aIID, getter_AddRefs(rawInterface));
    if (NS_FAILED(rv) || !rawInterface) {
        NS_ASSERTION(NS_FAILED(rv), "where did my rawInterface object go!");
        return nsnull;
    }

    peo = new nsProxyEventObject(destQueue, 
                                 proxyType, 
                                 rawInterface, 
                                 proxyClazz, 
                                 rootProxy,
                                 eventQService);
    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...
    //
    peo->mNext       = rootProxy->mNext;
    rootProxy->mNext = peo;

    NS_ADDREF(peo);
    return peo;  

}

Here is the call graph for this function:

Definition at line 130 of file nsProxyEventPrivate.h.

{ return (mProxyObject ? mProxyObject->GetProxyType() : nsnull);} 

Definition at line 128 of file nsProxyEventPrivate.h.

{ return (mProxyObject ? mProxyObject->GetQueue()     : nsnull);}
nsISupports* nsProxyEventObject::GetRealObject ( ) const [inline]

Definition at line 129 of file nsProxyEventPrivate.h.

{ return (mProxyObject ? mProxyObject->GetRealObject(): nsnull);}

Definition at line 378 of file nsProxyEventObject.cpp.

{
    if(aIID.Equals(mClass->GetProxiedIID())) {
        return this;
    }

    if(aIID.Equals(NS_GET_IID(nsISupports))) {
        return this;
    }

    nsProxyEventObject* cur = (mRoot ? mRoot : mNext);
    while(cur) {
        if(aIID.Equals(cur->GetClass()->GetProxiedIID())) {
            return cur;
        }
        cur = cur->mNext;
    }

    return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 153 of file nsProxyEventPrivate.h.

Definition at line 160 of file nsProxyEventPrivate.h.

Definition at line 154 of file nsProxyEventPrivate.h.

Definition at line 157 of file nsProxyEventPrivate.h.


The documentation for this class was generated from the following files: