// Cycles through the table periodically and cleans up expired entries. // private static void CleanupIdentities(Object state) { // FUTURE:: come up with a better way to do this BCLDebug.Assert( Thread.GetDomain().RemotingData.IDTableLock.IsWriterLockHeld, "ID Table being cleaned up without taking a lock!"); IDictionaryEnumerator e = URITable.GetEnumerator(); ArrayList removeList = new ArrayList(); while (e.MoveNext()) { Object o = e.Value; WeakReference wr = o as WeakReference; if ((null != wr) && (null == wr.Target)) { removeList.Add(e.Key); } } foreach (String key in removeList) { URITable.Remove(key); } }
[System.Security.SecurityCritical] // auto-generated internal static void RemoveIdentity(String uri, bool bResetURI) { Contract.Assert(uri != null, "Null URI"); BCLDebug.Trace("REMOTE", "IdentityHolder.WeakenIdentity ", uri, " for context ", Thread.CurrentContext); Identity id; String uriKey = MakeURIKey(uri); // We need to guarantee that finally is not interrupted so that the lock is released. // TableLock has a long path without reliability contract. To avoid adding contract on // the path, we will use ReaderWriterLock directly. ReaderWriterLock rwlock = TableLock; bool takeAndRelease = !rwlock.IsWriterLockHeld; RuntimeHelpers.PrepareConstrainedRegions(); try { if (takeAndRelease) { rwlock.AcquireWriterLock(INFINITE); } Object oRef = URITable[uriKey]; WeakReference wr = oRef as WeakReference; if (null != wr) { id = (Identity)wr.Target; wr.Target = null; } else { id = (Identity)oRef; if (id != null) { ((ServerIdentity)id).ResetHandle(); } } if (id != null) { URITable.Remove(uriKey); // Mark the ID as not present in the ID Table // This will clear its URI & objRef fields id.ResetInIDTable(bResetURI); } } finally { if (takeAndRelease && rwlock.IsWriterLockHeld) { rwlock.ReleaseWriterLock(); } } } // RemoveIdentity
private static void CleanupIdentities(object state) { IDictionaryEnumerator enumerator = URITable.GetEnumerator(); ArrayList list = new ArrayList(); while (enumerator.MoveNext()) { WeakReference reference = enumerator.Value as WeakReference; if ((reference != null) && (reference.Target == null)) { list.Add(enumerator.Key); } } foreach (string str in list) { URITable.Remove(str); } }
internal static void RemoveIdentity(string uri, bool bResetURI) { string key = MakeURIKey(uri); ReaderWriterLock tableLock = TableLock; bool flag = !tableLock.IsWriterLockHeld; RuntimeHelpers.PrepareConstrainedRegions(); try { Identity target; if (flag) { tableLock.AcquireWriterLock(0x7fffffff); } object obj2 = URITable[key]; WeakReference reference = obj2 as WeakReference; if (reference != null) { target = (Identity)reference.Target; reference.Target = null; } else { target = (Identity)obj2; if (target != null) { ((ServerIdentity)target).ResetHandle(); } } if (target != null) { URITable.Remove(key); target.ResetInIDTable(bResetURI); } } finally { if (flag && tableLock.IsWriterLockHeld) { tableLock.ReleaseWriterLock(); } } }
internal static void RemoveIdentity(String uri, bool bResetURI) { BCLDebug.Assert(uri != null, "Null URI"); BCLDebug.Trace("REMOTE", "IdentityHolder.WeakenIdentity ", uri, " for context ", Thread.CurrentContext); Identity id; String uriKey = MakeURIKey(uri); try { TableLock.AcquireWriterLock(INFINITE); Object oRef = URITable[uriKey]; WeakReference wr = oRef as WeakReference; if (null != wr) { id = (Identity)wr.Target; wr.Target = null; } else { id = (Identity)oRef; } if (id != null) { URITable.Remove(uriKey); // Mark the ID as not present in the ID Table // This will clear its URI & objRef fields id.ResetInIDTable(bResetURI); } } finally { TableLock.ReleaseWriterLock(); } } // RemoveIdentity
// Creates an identity entry. // This is used by Unmarshal and Marshal to generate the URI to identity // mapping // // private static Identity SetIdentity( Identity idObj, String URI, DuplicateIdentityOption duplicateOption) { // NOTE: This function assumes that a lock has been taken // by the calling function // idObj could be for a transparent proxy or a server object Message.DebugOut("SetIdentity:: domainid: " + Thread.GetDomainIDInternal() + "\n"); BCLDebug.Assert(null != idObj, "null != idObj"); // WriterLock must already be taken when SetIdentity is called! BCLDebug.Assert( TableLock.IsWriterLockHeld, "Should have write-locked the ID Table!"); // flag to denote that the id being set is a ServerIdentity bool bServerIDSet = idObj is ServerIdentity; if (null == idObj.URI) { // No URI has been associated with this identity. It must be a // server identity getting marshaled out of the app domain for // the first time. BCLDebug.Assert(bServerIDSet, "idObj should be ServerIdentity"); // Set the URI on the idObj (generating one if needed) idObj.SetOrCreateURI(URI); // If objectref is non-null make sure both have same URIs // (the URI in the objectRef could have potentially been reset // in a past external call to Disconnect() if (idObj.ObjectRef != null) { idObj.ObjectRef.URI = idObj.URI; } Message.DebugOut("SetIdentity: Generated URI " + URI + " for identity"); } // If we have come this far then there is no URI to identity // mapping present. Go ahead and create one. // ID should have a URI by now. BCLDebug.Assert(null != idObj.URI, "null != idObj.URI"); // See if this identity is already present in the Uri table String uriKey = MakeURIKey(idObj.URI); Object o = URITable[uriKey]; // flag to denote that the id found in the table is a ServerIdentity bool bServerID; if (null != o) { // We found an identity (or a WeakRef to one) for the URI provided WeakReference wr = o as WeakReference; Identity idInTable = null; if (wr != null) { // The object we found is a weak referece to an identity // This could be an identity for a client side // proxy // OR // a server identity which has been weakened since its life // is over. idInTable = (Identity)wr.Target; bServerID = idInTable is ServerIdentity; // If we find a weakRef for a ServerId we will be converting // it to a strong one before releasing the IdTable lock. BCLDebug.Assert( (idInTable == null) || (!bServerID || idInTable.IsRemoteDisconnected()), "Expect to find WeakRef only for remotely disconnected ids"); // We could find a weakRef to a client ID that does not // match the idObj .. but that is a handled race case // during Unmarshaling .. SetIdentity() will return the ID // from the table to the caller. } else { // We found a non-weak (strong) Identity for the URI idInTable = (Identity)o; bServerID = idInTable is ServerIdentity; //We dont put strong refs to client "Identity"s in the table BCLDebug.Assert( bServerID, "Found client side strong ID in the table"); } if ((idInTable != null) && (idInTable != idObj)) { // We are trying to add another identity for the same URI switch (duplicateOption) { case DuplicateIdentityOption.Unique: { String tempURI = idObj.URI; // Throw an exception to indicate the error since this could // be caused by a user trying to marshal two objects with the same // URI throw new RemotingException( String.Format(Environment.GetResourceString("Remoting_URIClash"), tempURI)); } // case DuplicateIdentityOption.Unique case DuplicateIdentityOption.UseExisting: { // This would be a case where our thread lost the race // we will return the one found in the table idObj = idInTable; break; } // case DuplicateIdentityOption.UseExisting: default: { BCLDebug.Assert(false, "Invalid DuplicateIdentityOption"); break; } } // switch (duplicateOption) } else if (wr != null) { // We come here if we found a weakRef in the table but // the target object had been cleaned up // OR // If there was a weakRef in the table and the target // object matches the idObj just passed in // Strengthen the entry if it a ServerIdentity. if (bServerID) { URITable[uriKey] = idObj; } else { // For client IDs associate the table entry // with the one passed in. // (If target was null we would set it ... // if was non-null then it matches idObj anyway) wr.Target = idObj; } } } else { // We did not find an identity entry for the URI Object addMe = null; if (bServerIDSet) { addMe = idObj; } else { addMe = new WeakReference(idObj); } // Add the entry into the table URITable.Add(uriKey, addMe); idObj.SetInIDTable(); // After every fixed number of set-id calls we run through // the table and cleanup if needed. SetIDCount++; if (SetIDCount % CleanUpCountInterval == 0) { // This should be called with the write lock held! // (which is why we assert that at the beginning of this // method) CleanupIdentities(null); } } Message.DebugOut("SetIdentity:: Identity::URI: " + idObj.URI + "\n"); return(idObj); }
private static Identity SetIdentity(Identity idObj, string URI, DuplicateIdentityOption duplicateOption) { bool flag = idObj is ServerIdentity; if (idObj.URI == null) { idObj.SetOrCreateURI(URI); if (idObj.ObjectRef != null) { idObj.ObjectRef.URI = idObj.URI; } } string key = MakeURIKey(idObj.URI); object obj2 = URITable[key]; if (obj2 != null) { bool flag2; WeakReference reference = obj2 as WeakReference; Identity target = null; if (reference != null) { target = (Identity)reference.Target; flag2 = target is ServerIdentity; } else { target = (Identity)obj2; flag2 = target is ServerIdentity; } if ((target != null) && (target != idObj)) { switch (duplicateOption) { case DuplicateIdentityOption.Unique: { string uRI = idObj.URI; throw new RemotingException(Environment.GetResourceString("Remoting_URIClash", new object[] { uRI })); } case DuplicateIdentityOption.UseExisting: idObj = target; return(idObj); } return(idObj); } if (reference != null) { if (flag2) { URITable[key] = idObj; return(idObj); } reference.Target = idObj; } return(idObj); } object obj3 = null; if (flag) { obj3 = idObj; ((ServerIdentity)idObj).SetHandle(); } else { obj3 = new WeakReference(idObj); } URITable.Add(key, obj3); idObj.SetInIDTable(); SetIDCount++; if ((SetIDCount % 0x40) == 0) { CleanupIdentities(null); } return(idObj); }