Esempio n. 1
0
        /*public*/ void IStateClientManager.Set(String id, SessionStateItem item, bool inStorage)
        {
            string        key           = CreateSessionStateCacheKey(id);
            bool          doInsert      = true;
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;

            Debug.Assert(!item.locked, "!item.locked");
            Debug.Assert(item.lockAge == TimeSpan.Zero, "item.lockAge == TimeSpan.Zero");

            if (inStorage)
            {
                Debug.Assert(item.lockCookie != 0, "item.lockCookie != 0");
                InProcSessionState stateCurrent = (InProcSessionState)cacheInternal.Get(key);

                /* If the state isn't there, we probably took too long to run. */
                if (stateCurrent == null)
                {
                    return;
                }

                Debug.Trace("SessionStateClientSet", "state is inStorage; key = " + key);

                stateCurrent.spinLock.AcquireWriterLock();
                try {
                    /* Only set the state if we are the owner */
                    if (!stateCurrent.locked || stateCurrent.lockCookie != item.lockCookie)
                    {
                        Debug.Trace("SessionStateClientSet", "Leave because we're not the owner; key = " + key);
                        return;
                    }

                    /* We can change the state in place if the timeout hasn't changed */
                    if (stateCurrent.timeout == item.timeout)
                    {
                        stateCurrent.Copy(
                            item.dict,
                            item.staticObjects,
                            item.timeout,
                            item.isCookieless,
                            item.streamLength,
                            false,
                            DateTime.MinValue,
                            item.lockCookie);

                        doInsert = false;
                        Debug.Trace("SessionStateClientSet", "Changing state inplace; key = " + key);
                    }
                    else
                    {
                        /* prevent overwriting when we drop the lock */
                        stateCurrent.lockCookie = 0;
                    }
                }
                finally {
                    stateCurrent.spinLock.ReleaseWriterLock();
                }
            }
            else
            {
                PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
                PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);

                TraceSessionStats();
            }

            if (doInsert)
            {
                Debug.Trace("SessionStateClientSet", "Inserting state into Cache; key = " + key);
                InProcSessionState state = new InProcSessionState(
                    item.dict,
                    item.staticObjects,
                    item.timeout,
                    item.isCookieless,
                    item.streamLength,
                    false,
                    DateTime.MinValue,
                    1);

                cacheInternal.UtcInsert(
                    key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state.timeout, 0),
                    CacheItemPriority.NotRemovable, s_callback);
            }
        }
        public override void SetAndReleaseItemExclusive(HttpContext context,
                                                        String id,
                                                        SessionStateStoreData item,
                                                        object lockId,
                                                        bool newItem)
        {
            string        key                         = CreateSessionStateCacheKey(id);
            bool          doInsert                    = true;
            CacheInternal cacheInternal               = HttpRuntime.CacheInternal;
            int           lockCookieForInsert         = NewLockCookie;
            ISessionStateItemCollection items         = null;
            HttpStaticObjectsCollection staticObjects = null;

            Debug.Assert(item.Items != null, "item.Items != null");
            Debug.Assert(item.StaticObjects != null, "item.StaticObjects != null");
            Debug.Assert(item.Timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES, "item.Timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES");

            SessionIDManager.CheckIdLength(id, true /* throwOnFail */);

            if (item.Items.Count > 0)
            {
                items = item.Items;
            }

            if (!item.StaticObjects.NeverAccessed)
            {
                staticObjects = item.StaticObjects;
            }

            if (!newItem)
            {
                Debug.Assert(lockId != null, "lockId != null");
                InProcSessionState stateCurrent = (InProcSessionState)cacheInternal.Get(key);
                int lockCookie = (int)lockId;

                /* If the state isn't there, we probably took too long to run. */
                if (stateCurrent == null)
                {
                    return;
                }

                Debug.Trace("SessionStateClientSet", "state is inStorage; key = " + key);
                Debug.Assert((stateCurrent._flags & (int)SessionStateItemFlags.Uninitialized) == 0, "Should never set an unitialized item; key = " + key);

                stateCurrent._spinLock.AcquireWriterLock();

                try {
                    /* Only set the state if we are the owner */
                    if (!stateCurrent._locked || stateCurrent._lockCookie != lockCookie)
                    {
                        Debug.Trace("SessionStateClientSet", "Leave because we're not the owner; key = " + key);
                        return;
                    }

                    /* We can change the state in place if the timeout hasn't changed */
                    if (stateCurrent._timeout == item.Timeout)
                    {
                        stateCurrent.Copy(
                            items,
                            staticObjects,
                            item.Timeout,
                            false,
                            DateTime.MinValue,
                            lockCookie,
                            stateCurrent._flags);

                        // Don't need to insert into the Cache because an in-place copy is good enough.
                        doInsert = false;
                        Debug.Trace("SessionStateClientSet", "Changing state inplace; key = " + key);
                    }
                    else
                    {
                        /* We are going to insert a new item to replace the current one in Cache
                         * because the expiry time has changed.
                         *
                         * Pleas note that an insert will cause the Session_End to be incorrectly raised.
                         *
                         * Please note that the item itself should not expire between now and
                         * where we do UtcInsert below because CacheInternal.Get above have just
                         * updated its expiry time.
                         */
                        stateCurrent._flags |= (int)SessionStateItemFlags.IgnoreCacheItemRemoved;

                        /* By setting _lockCookie to 0, we prevent an overwriting by ReleaseExclusive
                         * when we drop the lock.
                         * The scenario can happen if another request is polling and trying to prempt
                         * the lock we have on the item.
                         */
                        lockCookieForInsert      = lockCookie;
                        stateCurrent._lockCookie = 0;
                    }
                }
                finally {
                    stateCurrent._spinLock.ReleaseWriterLock();
                }
            }

            if (doInsert)
            {
                Debug.Trace("SessionStateClientSet", "Inserting state into Cache; key = " + key);
                InProcSessionState state = new InProcSessionState(
                    items,
                    staticObjects,
                    item.Timeout,
                    false,
                    DateTime.MinValue,
                    lockCookieForInsert,
                    0);

                try {
                }
                finally {
                    // protected from ThreadAbortEx
                    cacheInternal.UtcInsert(
                        key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state._timeout, 0),
                        CacheItemPriority.NotRemovable, _callback);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);

                    TraceSessionStats();
                }
            }
        }
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            string        key           = this.CreateSessionStateCacheKey(id);
            bool          flag          = true;
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            int           newLockCookie = NewLockCookie;
            ISessionStateItemCollection sessionItems  = null;
            HttpStaticObjectsCollection staticObjects = null;

            SessionIDManager.CheckIdLength(id, true);
            if (item.Items.Count > 0)
            {
                sessionItems = item.Items;
            }
            if (!item.StaticObjects.NeverAccessed)
            {
                staticObjects = item.StaticObjects;
            }
            if (!newItem)
            {
                InProcSessionState state = (InProcSessionState)cacheInternal.Get(key);
                int lockCookie           = (int)lockId;
                if (state == null)
                {
                    return;
                }
                state._spinLock.AcquireWriterLock();
                try
                {
                    if (!state._locked || (state._lockCookie != lockCookie))
                    {
                        return;
                    }
                    if (state._timeout == item.Timeout)
                    {
                        state.Copy(sessionItems, staticObjects, item.Timeout, false, DateTime.MinValue, lockCookie, state._flags);
                        flag = false;
                    }
                    else
                    {
                        state._flags     |= 2;
                        newLockCookie     = lockCookie;
                        state._lockCookie = 0;
                    }
                }
                finally
                {
                    state._spinLock.ReleaseWriterLock();
                }
            }
            if (flag)
            {
                InProcSessionState state2 = new InProcSessionState(sessionItems, staticObjects, item.Timeout, false, DateTime.MinValue, newLockCookie, 0);
                try
                {
                }
                finally
                {
                    cacheInternal.UtcInsert(key, state2, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state2._timeout, 0), CacheItemPriority.NotRemovable, this._callback);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
                }
            }
        }