Esempio n. 1
0
        public Option <TWeakOwningKey> GetPossibleWeakKeyFromValue(TContained contained)
        {
            lock (mLock)
            {
                foreach (var wrn in ContainedToKeyAndNeutralizeKillShot.GetValueIfPresent(contained).ToEnumerable())
                {
                    if (wrn.Item1.TryGetTarget(out var possible))
                    {
                        return(Some(possible));
                    }
                }

                return(None <TWeakOwningKey>());
            }
        }
Esempio n. 2
0
        private Either <TWeakOwningKey, T> AddUtility <T>(TContained contained, Func <TWeakOwningKey> buildNewResourceKey, Func <TContained, TWeakOwningKey, T> toReturnIfAlreadyExists)
        {
            lock (mLock)
            {
                foreach (var wrn in ContainedToKeyAndNeutralizeKillShot.GetValueIfPresent(contained).ToEnumerable())
                {
                    if (wrn.Item1.TryGetTarget(out var possible))
                    {
                        return(Either <TWeakOwningKey, T> .FromRight(toReturnIfAlreadyExists(contained, possible)));
                    }
                    else
                    {
                        // ** IMPORTANT ** - we failed to get the weak back - the weak-key is gone, ergo while there is a contained object here, it's to be considered defunct.
                        // However, theoretically, an outstanding killshot could be hanging on this lock to remove ContainedToKey.

                        wrn.Item2();                                           // don't want it to come back and kill the one we will add

                        ContainedToKeyAndNeutralizeKillShot.Remove(contained); // remove it ourself, now that noone else will

                        // Will fall through and rebuild the entry.
                    }
                }

                // build it.
                var resourceKey = buildNewResourceKey();

                var(newKeyHolder, neutralizeKillShot) = NewKeyHolderAndNeutralizeKillShot(mLock, ContainedToKeyAndNeutralizeKillShot, contained);
                KeyToContained.Add(
                    resourceKey,
                    Tuple.Create(
                        contained,
                        newKeyHolder));

                ContainedToKeyAndNeutralizeKillShot.Add(contained, Tuple.Create(new WeakReference <TWeakOwningKey>(resourceKey), neutralizeKillShot));
                return(Either <TWeakOwningKey, T> .FromLeft(resourceKey));
            }
        }