Ejemplo n.º 1
0
        //  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);
        }