Changeset 3058 in vbox for trunk/src/libs/xpcom18a4/ipc/ipcd
- Timestamp:
- Jun 5, 2007 9:42:29 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
r3055 r3058 234 234 count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); 235 235 if (0 == count) { 236 //mRefCnt = 1; /* stabilize */236 mRefCnt = 1; /* stabilize */ 237 237 // ipcDConnectService is guaranteed to still exist here 238 238 // (DConnectInstance lifetime is bound to ipcDConnectService) … … 247 247 return count; 248 248 } 249 250 // this gets called after calling AddRef() on an instance passed to the251 // client over IPC in order to have a count of IPC client-related references252 // separately from the overall reference count253 NS_IMETHODIMP_(nsrefcnt) AddRefIPC(void)254 {255 NS_PRECONDITION(PRInt32(mRefCntIPC) >= 0, "illegal refcnt");256 nsrefcnt count;257 count = PR_AtomicIncrement((PRInt32*)&mRefCntIPC);258 return count;259 }260 261 // this gets called before calling Release() when DCON_OP_RELEASE is262 // received from the IPC client263 NS_IMETHODIMP_(nsrefcnt) ReleaseIPC(void)264 {265 NS_PRECONDITION(0 != mRefCntIPC, "dup release");266 nsrefcnt count;267 count = PR_AtomicDecrement((PRInt32 *)&mRefCntIPC);268 return count;269 }270 249 271 250 private: 272 251 nsAutoRefCnt mRefCnt; 273 nsAutoRefCnt mRefCntIPC;274 252 PRUint32 mPeer; // peer process "owning" this instance 275 253 nsCOMPtr<nsIInterfaceInfo> mIInfo; … … 281 259 { 282 260 for (PRInt32 i=0; i<wrappers.Count(); ++i) 283 {284 ((DConnectInstance *) wrappers[i])->ReleaseIPC();285 261 ((DConnectInstance *) wrappers[i])->Release(); 286 }287 262 } 288 263 … … 1131 1106 1132 1107 // wrapper remains referenced when passing it to the client 1133 // (will be released upon DCON_OP_RELEASE). increase the 1134 // second, IPC-only, reference counter 1135 wrapper->AddRefIPC(); 1108 // (will be released upon DCON_OP_RELEASE) 1136 1109 1137 1110 // send address of the instance wrapper, and set the low bit … … 1400 1373 1401 1374 // wrapper remains referenced when passing it to the client 1402 // (will be released upon DCON_OP_RELEASE). increase the 1403 // second, IPC-only, reference counter 1404 wrapper->AddRefIPC(); 1405 1375 // (will be released upon DCON_OP_RELEASE) 1376 1406 1377 // send address of the instance wrapper, and set the low bit 1407 1378 // to indicate that this is an instance wrapper. … … 1676 1647 1677 1648 if (0 == count) { 1678 //mRefCnt = 1; /* stabilize */1649 mRefCnt = 1; /* stabilize */ 1679 1650 delete this; 1680 1651 return 0; … … 2703 2674 if (args && args->clientID == aData->Peer()) 2704 2675 { 2705 // add a fake reference to hold the wrapper alive 2706 nsrefcnt count = aData->AddRef(); 2707 2708 // release all IPC references for this wrapper, the client is now 2709 // officially dead (and thus cannot call AddRefIPC in the middle) 2710 nsrefcnt countIPC = aData->AddRefIPC(); 2711 countIPC = aData->ReleaseIPC(); 2712 2713 LOG(("ipcDConnectService::PruneInstanceMapForPeer: " 2714 "instance=%p: %d IPC refs to release (total refcnt=%d)\n", 2715 aData, countIPC, count)); 2716 2717 while (countIPC) 2718 { 2719 countIPC = aData->ReleaseIPC(); 2720 aData->Release(); 2721 } 2722 2676 // ignore the reference counter: the client is officially dead 2677 args->that->DeleteInstance(aData, PR_TRUE /* locked */); 2723 2678 // collect the instance for future destruction 2724 2679 if (!args->wrappers.AppendElement(aData)) … … 2762 2717 } 2763 2718 2764 LOG(("ipcDConnectService::OnClientStateChange: " 2765 "%d lost instances (should be 0 unless the peer has " 2766 "crashed)\n", wrappers.Count())); 2767 2768 // release all fake references we've added in PruneInstanceMapForPeer(). 2769 // this may call wrapper destructors so it's important to do that 2770 // outside the lock because destructors will release the real 2771 // objects which may need to make asynchronous use our service 2719 // destruct all instances outside the lock because it will release 2720 // the real objects which may need to make asynchronous use our service 2772 2721 for (PRInt32 i = 0; i < wrappers.Count(); ++i) 2773 ((DConnectInstance *) wrappers[i])->Release();2722 delete ((DConnectInstance *) wrappers[i]); 2774 2723 } 2775 2724 } … … 2927 2876 2928 2877 // wrapper remains referenced when passing it to the client 2929 // (will be released upon DCON_OP_RELEASE). increase the 2930 // second, IPC-only, reference counter 2931 wrapper->AddRefIPC(); 2878 // (will be released upon DCON_OP_RELEASE) 2932 2879 } 2933 2880 } … … 3000 2947 if (mInstanceSet.Contains(wrapper)) 3001 2948 { 3002 // add a fake reference to hold the wrapper alive3003 2949 nsrefcnt count = wrapper->AddRef(); 3004 3005 // release references3006 nsrefcnt countIPC = wrapper->ReleaseIPC();3007 2950 count = wrapper->Release(); 3008 3009 NS_ASSERTION(count > 0, "unbalanced AddRef()/Release()");3010 3011 2951 if (count == 1) 3012 2952 { 3013 NS_ASSERTION(countIPC == 0, "unbalanced AddRefIPC()/ReleaseIPC()");3014 3015 2953 // we are the last one who holds a (fake) reference, remove the 3016 2954 // instace from instance maps while still under the lock 3017 2955 DeleteInstance(wrapper, PR_TRUE /* locked */); 3018 3019 2956 // leave the lock before calling the destructor because it will release 3020 2957 // the real object which may need to make asynchronous use our service 3021 2958 lock.unlock(); 3022 2959 delete wrapper; 3023 }3024 else3025 {3026 // release the fake reference3027 wrapper->Release();3028 2960 } 3029 2961 }
Note:
See TracChangeset
for help on using the changeset viewer.