diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h')
-rw-r--r-- | src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h new file mode 100644 index 00000000..517b2650 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h @@ -0,0 +1,365 @@ +/* vim:set ts=2 sw=2 et cindent: */ +/* ***** 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 + * 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 IPC. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@meer.net> + * Dmitry A. Kuminov <dmik@innotek.de> + * + * Alternatively, the contents of this file may be used under the terms of + * either 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 ***** */ + +// DConnect service is multithreaded by default... +#if !defined(DCONNECT_SINGLETHREADED) && !defined(DCONNECT_MULTITHREADED) +#define DCONNECT_MULTITHREADED +# ifdef VBOX +//# define DCONNECT_WITH_IPRT_REQ_POOL +# endif +#endif + +#include "ipcIDConnectService.h" +#include "ipcdclient.h" + +#include "nsIInterfaceInfo.h" +#include "nsIInterfaceInfoManager.h" + +#include "nsCOMPtr.h" +#include "nsAutoPtr.h" +#include "nsDataHashtable.h" +#include "nsHashKeys.h" +#include "nsHashSets.h" +#include "nsVoidArray.h" +#include "nsAutoLock.h" +#include "xptcall.h" +#include "xptinfo.h" + +#if defined(DCONNECT_MULTITHREADED) +# if defined(DCONNECT_WITH_IPRT_REQ_POOL) + +# include <iprt/req.h> + +# else /* !DCONNECT_WITH_IPRT_REQ_POOL*/ + +#include "ipcList.h" + +struct DConnectOp; + +struct DConnectRequest : public ipcListNode<DConnectRequest> +{ + DConnectRequest (PRUint32 aPeer, const DConnectOp *aOp, PRUint32 aOpLen) + : peer(aPeer) + , opLen(aOpLen) + { + op = (const DConnectOp *) malloc(aOpLen); + memcpy ((void *) op, aOp, aOpLen); + } + ~DConnectRequest() { free((void *) op); } + + const PRUint32 peer; + const DConnectOp *op; + const PRUint32 opLen; +}; + +# endif // !DCONNECT_WITH_IPRT_REQ_POOL +#endif // DCONNECT_MULTITHREADED + +class nsIException; +class ipcMessageReader; +class ipcMessageWriter; + +// a key class used to identify DConnectInstance objects stored in a hash table +// by a composite of peer ID, XPCOM object pointer and IID this pointer represents + +class DConnectInstanceKey : public PLDHashEntryHdr +{ +public: + struct Key + { + Key(PRUint32 aPeer, const nsISupports *aObj, const nsID *aIID) + : mPeer (aPeer), mObj (aObj), mIID (aIID) {} + const PRUint32 mPeer; + const nsISupports *mObj; + const nsIID *mIID; + }; + + typedef const Key &KeyType; + typedef const Key *KeyTypePointer; + + DConnectInstanceKey(const Key *aKey) : mKey (*aKey) {} + DConnectInstanceKey(const DConnectInstanceKey &toCopy) : mKey (toCopy.mKey) {} + ~DConnectInstanceKey() {} + + KeyType GetKey() const { return mKey; } + KeyTypePointer GetKeyPointer() const { return &mKey; } + + PRBool KeyEquals(KeyTypePointer aKey) const { + return mKey.mPeer == aKey->mPeer && + mKey.mObj == aKey->mObj && + mKey.mIID->Equals(*aKey->mIID); + } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) { + return aKey->mPeer ^ + (NS_PTR_TO_INT32(aKey->mObj) >> 2) ^ + nsIDHashKey::HashKey(aKey->mIID); + } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const Key mKey; +}; + +class DConnectInstance; +typedef nsDataHashtable<DConnectInstanceKey, DConnectInstance *> DConnectInstanceMap; + +// extend nsVoidHashSet for compatibility with some nsTHashtable methods +class DConnectInstanceSet : public nsVoidHashSet +{ +public: + PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE) { + return nsVoidHashSet::Init(initSize) == NS_OK; + } + void Clear() { + PL_DHashTableEnumerate(&mHashTable, PL_DHashStubEnumRemove, nsnull); + } +}; + +typedef PRUint64 DConAddr; + +// a key class used to identify DConnectStub objects stored in a hash table +// by a composite of peer ID and DConAddr + +class DConnectStubKey : public PLDHashEntryHdr +{ +public: + struct Key + { + Key(PRUint32 aPeer, const DConAddr aInstance) + : mPeer (aPeer), mInstance (aInstance) {} + const PRUint32 mPeer; + const DConAddr mInstance; + }; + + typedef const Key &KeyType; + typedef const Key *KeyTypePointer; + + DConnectStubKey(const Key *aKey) : mKey (*aKey) {} + DConnectStubKey(const DConnectStubKey &toCopy) : mKey (toCopy.mKey) {} + ~DConnectStubKey() {} + + KeyType GetKey() const { return mKey; } + KeyTypePointer GetKeyPointer() const { return &mKey; } + + PRBool KeyEquals(KeyTypePointer aKey) const { + return mKey.mPeer == aKey->mPeer && + mKey.mInstance == aKey->mInstance; + } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) { + return aKey->mPeer ^ + (NS_PTR_TO_INT32(aKey->mInstance) >> 2); + } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const Key mKey; +}; + +// used elsewhere like nsAtomTable to safely represent the integral value +// of an address. +typedef PRUint64 PtrBits; + +// bit flag that defines if a PtrBits value represents a remote object +#define PTRBITS_REMOTE_BIT 0x1 + +class DConnectStub; +typedef nsDataHashtable<DConnectStubKey, DConnectStub *> DConnectStubMap; + +class ipcDConnectService : public ipcIDConnectService + , public ipcIMessageObserver + , public ipcIClientObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_IPCIDCONNECTSERVICE + NS_DECL_IPCIMESSAGEOBSERVER + NS_DECL_IPCICLIENTOBSERVER + + ipcDConnectService(); + + NS_HIDDEN_(nsresult) Init(); + NS_HIDDEN_(void) Shutdown(); + + NS_HIDDEN_(nsresult) GetInterfaceInfo(const nsID &iid, nsIInterfaceInfo **); + NS_HIDDEN_(nsresult) GetIIDForMethodParam(nsIInterfaceInfo *iinfo, + const nsXPTMethodInfo *methodInfo, + const nsXPTParamInfo ¶mInfo, + const nsXPTType &type, + PRUint16 methodIndex, + nsXPTCMiniVariant *dispatchParams, + PRBool isXPTCVariantArray, + nsID &result); + + NS_HIDDEN_(nsresult) SerializeInterfaceParam(ipcMessageWriter &writer, + PRUint32 peer, const nsID &iid, + nsISupports *obj, + nsVoidArray &wrappers); + NS_HIDDEN_(nsresult) DeserializeInterfaceParamBits(PtrBits bits, PRUint32 peer, + const nsID &iid, + nsISupports *&obj); + + NS_HIDDEN_(nsresult) SerializeException(ipcMessageWriter &writer, + PRUint32 peer, nsIException *xcpt, + nsVoidArray &wrappers); + NS_HIDDEN_(nsresult) DeserializeException(ipcMessageReader &reader, + PRUint32 peer, nsIException **xcpt); + + NS_HIDDEN_(void) ReleaseWrappers(nsVoidArray &wrappers, PRUint32 peer); + + NS_HIDDEN_(nsresult) CreateStub(const nsID &, PRUint32, DConAddr, DConnectStub **); +#if 0 + NS_HIDDEN_(PRBool) FindStubAndAddRef(PRUint32, const DConAddr, DConnectStub **); +#endif + // public only for DConnectStub::~DConnectStub() + NS_HIDDEN_(void) DeleteStub(DConnectStub *); + + // public only for DConnectInstance::Release() + NS_HIDDEN_(void) DeleteInstance(DConnectInstance *, PRBool locked = PR_FALSE); + // public only for DConnectStub::CallMethod() + NS_HIDDEN_(PRBool) CheckInstanceAndAddRef(DConnectInstance *, PRUint32); + + PRLock *StubLock() { return mStubLock; } + PRLock *StubQILock() { return mStubQILock; } + + static nsRefPtr <ipcDConnectService> GetInstance() { + return nsRefPtr <ipcDConnectService> (mInstance); + } + +private: + + NS_HIDDEN ~ipcDConnectService(); + + NS_HIDDEN_(nsresult) StoreInstance(DConnectInstance *); + NS_HIDDEN_(PRBool) FindInstanceAndAddRef(PRUint32, + const nsISupports *, + const nsIID *, + DConnectInstance **); + + NS_HIDDEN_(nsresult) StoreStub(DConnectStub *); + + NS_HIDDEN_(void) OnIncomingRequest(PRUint32 peer, const struct DConnectOp *op, PRUint32 opLen); + + NS_HIDDEN_(void) OnSetup(PRUint32 peer, const struct DConnectSetup *, PRUint32 opLen); + NS_HIDDEN_(void) OnRelease(PRUint32 peer, const struct DConnectRelease *); + NS_HIDDEN_(void) OnInvoke(PRUint32 peer, const struct DConnectInvoke *, PRUint32 opLen); + +#if defined(DCONNECT_MULTITHREADED) +# if defined(DCONNECT_WITH_IPRT_REQ_POOL) + static DECLCALLBACK(void) ProcessMessageOnWorkerThread(ipcDConnectService *aThis, PRUint32 aSenderID, void *aData, PRUint32 aDataLen); +# else + NS_HIDDEN_(nsresult) CreateWorker(); +# endif +#endif + +private: + nsCOMPtr<nsIInterfaceInfoManager> mIIM; + + // lock to protect access to instance sets and the disconnected flag + PRLock *mLock; + + // table of local object instances allocated on behalf of a peer + // (keys are interface pointers of real objects these instances represent) + DConnectInstanceMap mInstances; + // hashset containing the same instances as above + // (used for quick parameter validity checks) + DConnectInstanceSet mInstanceSet; + + // lock to protect access to mStubs and DConnectStub::mRefCntLevels + // (also guards every DConnectStub::Release call to provide atomicity) + PRLock *mStubLock; + + // table of remote object stubs allocated to communicate with peer's instances + DConnectStubMap mStubs; + + // this is true after IPC_Shutdown() has been called + PRBool mDisconnected; + +// member is never initialized or used, no point in wasting memory or making +// someone believe it contains anything relevant +#ifndef VBOX + // our IPC client ID + PRUint32 mSelfID; +#endif + + // global lock to protect access to protect DConnectStub::QueryInterface() + // (we cannot use mStubLock because it isn't supposed to be held long, + // like in case of an IPC call and such) + PRLock *mStubQILock; + +#if defined(DCONNECT_MULTITHREADED) +# if defined(DCONNECT_WITH_IPRT_REQ_POOL) + + /** Request pool. */ + RTREQPOOL mhReqPool; + +# else + + friend class DConnectWorker; + + // pool of worker threads to serve incoming requests + nsVoidArray mWorkers; + // queue of pending requests + ipcList<DConnectRequest> mPendingQ; + // monitor to protect mPendingQ + PRMonitor *mPendingMon; + // number of waiting workers + PRUint32 mWaitingWorkers; + // monitor used to wait on changes in mWaitingWorkers. + PRMonitor *mWaitingWorkersMon; +# endif +#endif + + // global ipcDConnectService instance for internal usage + static ipcDConnectService *mInstance; +}; + +#define IPC_DCONNECTSERVICE_CLASSNAME \ + "ipcDConnectService" +#define IPC_DCONNECTSERVICE_CONTRACTID \ + "@mozilla.org/ipc/dconnect-service;1" +#define IPC_DCONNECTSERVICE_CID \ +{ /* 63a5d9dc-4828-425a-bd50-bd10a4b26f2c */ \ + 0x63a5d9dc, \ + 0x4828, \ + 0x425a, \ + {0xbd, 0x50, 0xbd, 0x10, 0xa4, 0xb2, 0x6f, 0x2c} \ +} |