/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * 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 http://www.mozilla.org/MPL/ * * 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 Sun Microsystems, * Inc. Portions created by Sun are * Copyright (C) 1999 Sun Microsystems, Inc. All * Rights Reserved. * * Contributor(s): * Igor Kushnirskiy */ #include "nsIGenericFactory.h" #include "nsIModule.h" #include "nsHashtable.h" #include "bcXPCOMStubsAndProxies.h" #include "bcXPCOMStub.h" #include "bcXPCOMProxy.h" #include "bcXPCOMLog.h" NS_GENERIC_FACTORY_CONSTRUCTOR(bcXPCOMStubsAndProxies); static nsModuleComponentInfo components[] = { { "Black Connect XPCOM stubs and proxies", BC_XPCOMSTUBSANDPROXIES_CID, BC_XPCOMSTUBSANDPROXIES_ContractID, bcXPCOMStubsAndProxiesConstructor } }; NS_IMPL_NSGETMODULE("BlackConnect XPCOM stubs and proxies",components); NS_IMPL_THREADSAFE_ISUPPORTS(bcXPCOMStubsAndProxies,NS_GET_IID(bcXPCOMStubsAndProxies)); class bcOIDKey : public nsHashKey { protected: bcOID key; public: bcOIDKey(bcOID oid) { key = oid; } virtual ~bcOIDKey() { } PRUint32 HashCode(void) const { return (PRUint32)key; } PRBool Equals(const nsHashKey *aKey) const { return (key == ((const bcOIDKey *) aKey)->key); } nsHashKey *Clone() const { return new bcOIDKey(key); } }; bcXPCOMStubsAndProxies::bcXPCOMStubsAndProxies() { NS_INIT_REFCNT(); oid2objectMap = new nsSupportsHashtable(256, PR_TRUE); threadPrivateIndex = 0; } bcXPCOMStubsAndProxies::~bcXPCOMStubsAndProxies() { delete oid2objectMap; } NS_IMETHODIMP bcXPCOMStubsAndProxies::GetStub(nsISupports *obj, bcIStub **stub) { if (!stub) { return NS_ERROR_NULL_POINTER; } *stub = new bcXPCOMStub(obj); return NS_OK; } NS_IMETHODIMP bcXPCOMStubsAndProxies::GetOID(nsISupports *obj, bcIORB *orb, bcOID *oid) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); bcOID *tmp; if (NS_SUCCEEDED(obj->QueryInterface(NS_GET_IID(bcXPCOMProxy),(void**)&tmp))) { *oid = *tmp; PR_LOG(log, PR_LOG_DEBUG,("--[c++] bcXPCOMProxy::GetOID obj %p is a proxy to oid %d\n",obj,*oid)); } else { bcIStub *stub = NULL; GetStub(obj, &stub); *oid = orb->RegisterStub(stub); oid2objectMap->Put(new bcOIDKey(*oid),obj); } return NS_OK; } NS_IMETHODIMP bcXPCOMStubsAndProxies::GetProxy(bcOID oid, const nsIID &iid, bcIORB *orb, nsISupports **proxy) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); nsresult rv = NS_OK; PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::GetProxy iid=%s\n",iid.ToString())); if (!proxy) { PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::GetProxy failed\n")); return NS_ERROR_NULL_POINTER; } *proxy = NULL; nsHashKey * key = new bcOIDKey(oid); *proxy = oid2objectMap->Get(key); //doing shortcut delete key; if (*proxy != NULL) { rv = (*proxy)->QueryInterface(iid,(void **)proxy); PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::GetProxy we have shortcut for oid=%d\n",oid)); } else { *proxy = new bcXPCOMProxy(oid,iid,orb); NS_IF_ADDREF(*proxy); } return rv; } struct EventQueueStack { PRUint32 stackPointer; nsIEventQueue *stack[200]; EventQueueStack() { stackPointer = 0; } }; NS_IMETHODIMP bcXPCOMStubsAndProxies::GetEventQueue(nsIEventQueue **eventQueue) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::GetEventQueue\n")); EventQueueStack *stack; if (threadPrivateIndex == 0) { *eventQueue = NULL; } else { stack = (EventQueueStack*)PR_GetThreadPrivate(threadPrivateIndex); if (stack !=0 && stack->stackPointer != 0) { *eventQueue = stack->stack[(stack->stackPointer)-1]; PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::GetEventQueue eventQueue=%p\n",*eventQueue)); NS_IF_ADDREF(*eventQueue); } else { *eventQueue = NULL; } } return NS_OK; } NS_IMETHODIMP bcXPCOMStubsAndProxies::PopEventQueue(nsIEventQueue **_eventQueue) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue\n")); EventQueueStack *stack; nsIEventQueue * eventQueue; if (threadPrivateIndex == 0) { *_eventQueue = NULL; PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue 1\n")); } else { stack = (EventQueueStack*)PR_GetThreadPrivate(threadPrivateIndex); if (stack !=0 && stack->stackPointer != 0) { PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue 2\n")); eventQueue = stack->stack[--(stack->stackPointer)]; } else { PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue 3\n")); eventQueue = NULL; } if (_eventQueue != NULL) { PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue 4\n")); *_eventQueue = eventQueue; } else { PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue eventQueue=%p\n",eventQueue)); NS_IF_RELEASE(eventQueue); } } PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PopEventQueue 6\n")); return NS_OK; } NS_IMETHODIMP bcXPCOMStubsAndProxies::PushEventQueue(nsIEventQueue *eventQueue) { PRLogModuleInfo *log = bcXPCOMLog::GetLog(); PR_LOG(log, PR_LOG_DEBUG, ("--bcXPCOMStubsAndProxies::PushEventQueue eventQueue=%p\n",eventQueue)); nsresult r; if (threadPrivateIndex == 0) { r = PR_NewThreadPrivateIndex(&threadPrivateIndex,NULL); PR_ASSERT(threadPrivateIndex != 0 && NS_SUCCEEDED(r)); } EventQueueStack *stack; stack = (EventQueueStack*)PR_GetThreadPrivate(threadPrivateIndex); if (stack == NULL) { stack = new EventQueueStack(); PR_SetThreadPrivate(threadPrivateIndex, (void *)stack); } NS_IF_ADDREF(eventQueue); stack->stack[(stack->stackPointer)++] = eventQueue; return NS_OK; }