[System.Security.SecurityCritical] // auto-generated
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.GetDomainID() + "\n");
Contract.Assert(null != idObj,"null != idObj");
// WriterLock must already be taken when SetIdentity is called!
Contract.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.
Contract.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.
Contract.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.
Contract.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 ---- 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
Contract.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(
Environment.GetResourceString("Remoting_URIClash",
tempURI));
} // case DuplicateIdentityOption.Unique
case DuplicateIdentityOption.UseExisting:
{
// This would be a case where our thread lost the ----
// we will return the one found in the table
idObj = idInTable;
break;
} // case DuplicateIdentityOption.UseExisting:
default:
{
Contract.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;
((ServerIdentity)idObj).SetHandle();
}
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;
}