// Unlock an item locked by GetExclusive
        // 'lockId' is the lock context returned by previous call to GetExclusive
        public override void ReleaseItemExclusive(HttpContext context,
                                                  String id,
                                                  object lockId)
        {
            Debug.Assert(lockId != null, "lockId != null");

            string key        = CreateSessionStateCacheKey(id);
            int    lockCookie = (int)lockId;

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

            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

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

            if (state._locked)
            {
                state._spinLock.AcquireWriterLock();
                try {
                    if (state._locked && lockCookie == state._lockCookie)
                    {
                        state._locked = false;
                    }
                }
                finally {
                    state._spinLock.ReleaseWriterLock();
                }
            }
        }
예제 #2
0
        /*public*/ void IStateClientManager.ReleaseExclusive(String id, int lockCookie)
        {
            string             key   = CreateSessionStateCacheKey(id);
            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

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

            if (state.locked)
            {
                state.spinLock.AcquireWriterLock();
                try {
                    if (state.locked && lockCookie == state.lockCookie)
                    {
                        state.locked = false;
                    }
                }
                finally {
                    state.spinLock.ReleaseWriterLock();
                }
            }
        }
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            string        key           = this.CreateSessionStateCacheKey(id);
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            int           num           = (int)lockId;

            SessionIDManager.CheckIdLength(id, true);
            InProcSessionState state = (InProcSessionState)cacheInternal.Get(key);

            if (state != null)
            {
                state._spinLock.AcquireWriterLock();
                try
                {
                    if (!state._locked || (state._lockCookie != num))
                    {
                        return;
                    }
                    state._lockCookie = 0;
                }
                finally
                {
                    state._spinLock.ReleaseWriterLock();
                }
                cacheInternal.Remove(key);
            }
        }
예제 #4
0
        /*public*/ void IStateClientManager.Remove(String id, int lockCookie)
        {
            string        key           = CreateSessionStateCacheKey(id);
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;

            InProcSessionState state = (InProcSessionState)cacheInternal.Get(key);

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

            state.spinLock.AcquireWriterLock();
            try {
                /* Only remove the item if we are the owner */
                if (!state.locked || state.lockCookie != lockCookie)
                {
                    return;
                }

                /* prevent overwriting when we drop the lock */
                state.lockCookie = 0;
            }
            finally {
                state.spinLock.ReleaseWriterLock();
            }

            cacheInternal.Remove(key);

            TraceSessionStats();
        }
 public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
 {
     string key = this.CreateSessionStateCacheKey(id);
     SessionIDManager.CheckIdLength(id, true);
     InProcSessionState state = new InProcSessionState(null, null, timeout, false, DateTime.MinValue, NewLockCookie, 1);
     try
     {
     }
     finally
     {
         if (HttpRuntime.CacheInternal.UtcAdd(key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, timeout, 0), CacheItemPriority.NotRemovable, this._callback) == null)
         {
             PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
             PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
         }
     }
 }
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            string key = this.CreateSessionStateCacheKey(id);

            SessionIDManager.CheckIdLength(id, true);
            InProcSessionState state = new InProcSessionState(null, null, timeout, false, DateTime.MinValue, NewLockCookie, 1);

            try
            {
            }
            finally
            {
                if (HttpRuntime.CacheInternal.UtcAdd(key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, timeout, 0), CacheItemPriority.NotRemovable, this._callback) == null)
                {
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
                }
            }
        }
예제 #7
0
        protected override SessionStateItem GetExclusive(String id)
        {
            string             key   = CreateSessionStateCacheKey(id);
            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

            if (state != null)
            {
                bool locked = true;     // True if the state is locked by another session

                // If unlocked, use a spinlock to test and lock the state.
                if (!state.locked)
                {
                    state.spinLock.AcquireWriterLock();
                    try {
                        if (!state.locked)
                        {
                            locked            = false;
                            state.locked      = true;
                            state.utcLockDate = DateTime.UtcNow;
                            state.lockCookie++;
                        }
                    }
                    finally {
                        state.spinLock.ReleaseWriterLock();
                    }
                }

                TimeSpan lockAge = locked ? DateTime.UtcNow - state.utcLockDate : TimeSpan.Zero;

                return(new SessionStateItem(
                           state.dict,
                           state.staticObjects,
                           state.timeout,
                           state.isCookieless,
                           state.streamLength,
                           locked,
                           lockAge,
                           state.lockCookie));
            }

            return(null);
        }
예제 #8
0
        protected override SessionStateItem Get(String id)
        {
            string             key   = CreateSessionStateCacheKey(id);
            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

            if (state != null)
            {
                return(new SessionStateItem(
                           state.dict,
                           state.staticObjects,
                           state.timeout,
                           state.isCookieless,
                           state.streamLength,
                           state.locked,
                           TimeSpan.Zero,
                           state.lockCookie));
            }

            return(null);
        }
        // Remove an item.  Note that the item is originally obtained by GetExclusive
        // Same note as Set on lockId
        public override void RemoveItem(HttpContext context,
                                        String id,
                                        object lockId,
                                        SessionStateStoreData item)
        {
            Debug.Assert(lockId != null, "lockId != null");

            string        key           = CreateSessionStateCacheKey(id);
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            int           lockCookie    = (int)lockId;

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

            InProcSessionState state = (InProcSessionState)cacheInternal.Get(key);

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

            state._spinLock.AcquireWriterLock();

            try {
                /* Only remove the item if we are the owner */
                if (!state._locked || state._lockCookie != lockCookie)
                {
                    return;
                }

                /* prevent overwriting when we drop the lock */
                state._lockCookie = 0;
            }
            finally {
                state._spinLock.ReleaseWriterLock();
            }

            cacheInternal.Remove(key);

            TraceSessionStats();
        }
예제 #10
0
        public override void CreateUninitializedItem(HttpContext context, String id, int timeout)
        {
            string key = CreateSessionStateCacheKey(id);

            Debug.Assert(timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES, "item.Timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES");

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

            Debug.Trace("SessionStateClientSet", "Inserting an uninitialized item into Cache; key = " + key);

            InProcSessionState state = new InProcSessionState(
                null,
                null,
                timeout,
                false,
                DateTime.MinValue,
                NewLockCookie,
                (int)SessionStateItemFlags.Uninitialized);

            // DevDivBugs 146875
            // We do not want to overwrite an item with an uninitialized item if it is
            // already in the cache
            try {
            }
            finally {
                // protected from ThreadAbortEx
                object existingEntry = HttpRuntime.Cache.InternalCache.Add(key, state, new CacheInsertOptions()
                {
                    SlidingExpiration = new TimeSpan(0, timeout, 0),
                    Priority          = CacheItemPriority.NotRemovable,
                    OnRemovedCallback = _callback
                });
                if (existingEntry == null)
                {
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
                }
            }
        }
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
        {
            string key = this.CreateSessionStateCacheKey(id);
            int    num = (int)lockId;

            SessionIDManager.CheckIdLength(id, true);
            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

            if ((state != null) && state._locked)
            {
                state._spinLock.AcquireWriterLock();
                try
                {
                    if (state._locked && (num == state._lockCookie))
                    {
                        state._locked = false;
                    }
                }
                finally
                {
                    state._spinLock.ReleaseWriterLock();
                }
            }
        }
        public void OnCacheItemRemoved(string key, object value, CacheItemRemovedReason reason)
        {
            PerfCounters.DecrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
            InProcSessionState state = (InProcSessionState)value;

            if (((state._flags & 2) == 0) && ((state._flags & 1) == 0))
            {
                switch (reason)
                {
                case CacheItemRemovedReason.Removed:
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ABANDONED);
                    break;

                case CacheItemRemovedReason.Expired:
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TIMED_OUT);
                    break;
                }
                if (this._expireCallback != null)
                {
                    string id = key.Substring(CACHEKEYPREFIXLENGTH);
                    this._expireCallback(id, SessionStateUtility.CreateLegitStoreData(null, state._sessionItems, state._staticObjects, state._timeout));
                }
            }
        }
        public override void CreateUninitializedItem(HttpContext context, String id, int timeout) {
            string          key = CreateSessionStateCacheKey(id);

            Debug.Assert(timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES, "item.Timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES");
            
            SessionIDManager.CheckIdLength(id, true /* throwOnFail */);

            Debug.Trace("SessionStateClientSet", "Inserting an uninitialized item into Cache; key = " + key);

            InProcSessionState state = new InProcSessionState(
                    null,
                    null,
                    timeout,
                    false,
                    DateTime.MinValue,
                    NewLockCookie,
                    (int)SessionStateItemFlags.Uninitialized);

            // DevDivBugs 146875
            // We do not want to overwrite an item with an uninitialized item if it is
            // already in the cache
            try {
            }
            finally {
                // protected from ThreadAbortEx
                object existingEntry = HttpRuntime.CacheInternal.UtcAdd(
                        key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, timeout, 0),
                        CacheItemPriority.NotRemovable, _callback);
                if (existingEntry == null) {
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
                    PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
                }
            }
        }
        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                         = 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);
                }
            }
        }
        SessionStateStoreData DoGet(HttpContext context,
                                    String id,
                                    bool exclusive,
                                    out bool locked,
                                    out TimeSpan lockAge,
                                    out object lockId,
                                    out SessionStateActions actionFlags)
        {
            string key = CreateSessionStateCacheKey(id);

            // Set default return values
            locked      = false;
            lockId      = null;
            lockAge     = TimeSpan.Zero;
            actionFlags = 0;

            // Not technically necessary for InProc, but we do it to be consistent
            // with SQL provider
            SessionIDManager.CheckIdLength(id, true /* throwOnFail */);

            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

            if (state != null)
            {
                bool lockedByOther;          // True if the state is locked by another session
                int  initialFlags;

                initialFlags = (int)state._flags;
                if ((initialFlags & (int)SessionStateItemFlags.Uninitialized) != 0)
                {
                    // It is an uninitialized item.  We have to remove that flag.
                    // We only allow one request to do that.
                    // For details, see inline doc for SessionStateItemFlags.Uninitialized flag.

                    // If initialFlags != return value of CompareExchange, it means another request has
                    // removed the flag.

                    Debug.Trace("SessionStateClientSet", "Removing the Uninit flag for item; key = " + key);
                    if (initialFlags == Interlocked.CompareExchange(
                            ref state._flags,
                            initialFlags & (~((int)SessionStateItemFlags.Uninitialized)),
                            initialFlags))
                    {
                        actionFlags = SessionStateActions.InitializeItem;
                    }
                }

                if (exclusive)
                {
                    lockedByOther = true;

                    // If unlocked, use a spinlock to test and lock the state.
                    if (!state._locked)
                    {
                        state._spinLock.AcquireWriterLock();
                        try {
                            if (!state._locked)
                            {
                                lockedByOther      = false;
                                state._locked      = true;
                                state._utcLockDate = DateTime.UtcNow;
                                state._lockCookie++;
                            }
                            lockId = state._lockCookie;
                        }
                        finally {
                            state._spinLock.ReleaseWriterLock();
                        }
                    }
                    else
                    {
                        // It's already locked by another request.  Return the lockCookie to caller.
                        lockId = state._lockCookie;
                    }
                }
                else
                {
                    state._spinLock.AcquireReaderLock();
                    try {
                        lockedByOther = state._locked;
                        lockId        = state._lockCookie;
                    }
                    finally {
                        state._spinLock.ReleaseReaderLock();
                    }
                }

                if (lockedByOther)
                {
                    // Item found, but locked
                    locked  = true;
                    lockAge = DateTime.UtcNow - state._utcLockDate;
                    return(null);
                }
                else
                {
                    return(SessionStateUtility.CreateLegitStoreData(context, state._sessionItems,
                                                                    state._staticObjects, state._timeout));
                }
            }

            // Not found
            return(null);
        }
        private SessionStateStoreData DoGet(HttpContext context, string id, bool exclusive, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
        {
            bool   flag;
            string key = this.CreateSessionStateCacheKey(id);

            locked      = false;
            lockId      = null;
            lockAge     = TimeSpan.Zero;
            actionFlags = SessionStateActions.None;
            SessionIDManager.CheckIdLength(id, true);
            InProcSessionState state = (InProcSessionState)HttpRuntime.CacheInternal.Get(key);

            if (state == null)
            {
                return(null);
            }
            int comparand = state._flags;

            if (((comparand & 1) != 0) && (comparand == Interlocked.CompareExchange(ref state._flags, comparand & -2, comparand)))
            {
                actionFlags = SessionStateActions.InitializeItem;
            }
            if (exclusive)
            {
                flag = true;
                if (!state._locked)
                {
                    state._spinLock.AcquireWriterLock();
                    try
                    {
                        if (!state._locked)
                        {
                            flag               = false;
                            state._locked      = true;
                            state._utcLockDate = DateTime.UtcNow;
                            state._lockCookie++;
                        }
                        lockId = state._lockCookie;
                        goto Label_00FE;
                    }
                    finally
                    {
                        state._spinLock.ReleaseWriterLock();
                    }
                }
                lockId = state._lockCookie;
            }
            else
            {
                state._spinLock.AcquireReaderLock();
                try
                {
                    flag   = state._locked;
                    lockId = state._lockCookie;
                }
                finally
                {
                    state._spinLock.ReleaseReaderLock();
                }
            }
Label_00FE:
            if (flag)
            {
                locked  = true;
                lockAge = (TimeSpan)(DateTime.UtcNow - state._utcLockDate);
                return(null);
            }
            return(SessionStateUtility.CreateLegitStoreData(context, state._sessionItems, state._staticObjects, state._timeout));
        }
 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);
         }
     }
 }
예제 #20
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);
            }
        }