Esempio n. 1
0
        /// <summary>
        /// Updates our entries in the dictionary. To be immediately visible as soon as
        /// the _items.CanCommit() passes, we add ourselves into the dict straight away,
        /// and in a side effect we remove unnecessary entries, or, on rollback, undo
        /// the early additions.
        /// </summary>
        void UpdateEntries()
        {
            Shield.Enlist(this, false, true);
            var l = new Locals();

            var oldItems = _items.GetOldValue();
            var newItems = _items.Value;

            l.PreAdd = newItems == null ? null :
                       (oldItems != null ? newItems.Except(oldItems).ToList() : newItems.ToList());
            l.CommitRemove = oldItems == null ? null :
                             (newItems != null ? oldItems.Except(newItems).ToList() : oldItems.ToList());
            try { }
            finally
            {
                _locals.Value = l;
                var newArray = new[] { this };
                // early adding
                if (l.PreAdd != null)
                {
                    foreach (var newKey in l.PreAdd)
                    {
                        lock (Context)
                            Context.AddOrUpdate(newKey,
                                                k => newArray,
                                                (k, existing) => existing.Concat(newArray).ToArray());
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Enlists the field in the current transaction and, if this is the first
        /// access, checks the write lock. Will wait (using StampLocker) if the write
        /// stamp &lt;= <see cref="Shield.ReadStamp"/>, until write lock is released.
        /// Since write stamps are increasing, this is likely to happen only at the
        /// beginning of transactions.
        /// </summary>
        private void CheckLockAndEnlist(bool write)
        {
            // if already enlisted, no need to check lock.
            if (!Shield.Enlist(this, _locals.HasValue, write))
            {
                return;
            }

            var ws = _writerStamp;

            if (ws != null && ws.Locked && ws.Version <= Shield.ReadStamp)
            {
                ws.Wait();
            }
        }
Esempio n. 3
0
        private void CheckLockAndEnlist(TKey key, bool write)
        {
            var locals = _localDict.HasValue ? _localDict.Value : null;

            if (locals != null && locals.Locked)
            {
                CheckLockedAccess(key, write);
                return; // because the check above is much stricter than anything
            }
            if (!Shield.Enlist(this, locals != null, write) && locals.Items.ContainsKey(key))
            {
                return;
            }

            WriteStamp w;

            if (_writeStamps.TryGetValue(key, out w) && w.Locked && w.Version <= Shield.ReadStamp)
            {
                w.Wait();
            }
        }