// 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); }