コード例 #1
0
        // Reset the expire time of an item based on its timeout value
        public override void ResetItemTimeout(HttpContext context, String id)
        {
            string key = CreateSessionStateCacheKey(id);

            SessionIDManager.CheckIdLength(id, true /* throwOnFail */);
            HttpRuntime.CacheInternal.Get(key);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        // 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();
                }
            }
        }
コード例 #4
0
        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);
                }
            }
        }
コード例 #5
0
        // 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();
        }
コード例 #6
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);
                }
            }
        }
コード例 #7
0
        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();
                }
            }
        }
コード例 #8
0
        void MakeRequest(
            UnsafeNativeMethods.StateProtocolVerb verb,
            String id,
            UnsafeNativeMethods.StateProtocolExclusive exclusiveAccess,
            int extraFlags,
            int timeout,
            int lockCookie,
            byte[]                                  buf,
            int cb,
            int networkTimeout,
            out UnsafeNativeMethods.SessionNDMakeRequestResults results)
        {
            int    hr;
            string uri;
            OutOfProcConnection conn = null;
            HandleRef           socketHandle;
            bool checkVersion = false;

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

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

            if (_partitionInfo == null)
            {
                Debug.Assert(s_partitionManager != null);
                Debug.Assert(_partitionResolver != null);

                _partitionInfo = (StateServerPartitionInfo)s_partitionManager.GetPartition(_partitionResolver, id);

                // If its still null, we give up
                if (_partitionInfo == null)
                {
                    throw new HttpException(SR.GetString(SR.Bad_partition_resolver_connection_string, "PartitionManager"));
                }
            }

            // Need to make sure we dispose the connection if anything goes wrong
            try {
                conn = (OutOfProcConnection)_partitionInfo.RetrieveResource();
                if (conn != null)
                {
                    socketHandle = new HandleRef(this, conn._socketHandle.Handle);
                }
                else
                {
                    socketHandle = new HandleRef(this, INVALID_SOCKET);
                }

                if (_partitionInfo.StateServerVersion == -1)
                {
                    // We don't need locking here because it's okay to have two
                    // requests initializing s_stateServerVersion.
                    checkVersion = true;
                }

                Debug.Trace("OutOfProcSessionStateStoreMakeRequest",
                            "Calling MakeRequest, " +
                            "socket=" + (IntPtr)socketHandle.Handle +
                            "verb=" + verb +
                            " id=" + id +
                            " exclusiveAccess=" + exclusiveAccess +
                            " timeout=" + timeout +
                            " buf=" + ((buf != null) ? "non-null" : "null") +
                            " cb=" + cb +
                            " checkVersion=" + checkVersion +
                            " extraFlags=" + extraFlags);

                // Have to UrlEncode id because it may contain non-URL-safe characters
                uri = HttpUtility.UrlEncode(s_uribase + id);

                hr = UnsafeNativeMethods.SessionNDMakeRequest(
                    socketHandle, _partitionInfo.Server, _partitionInfo.Port, _partitionInfo.ServerIsIPv6NumericAddress /* forceIPv6 */, networkTimeout, verb, uri,
                    exclusiveAccess, extraFlags, timeout, lockCookie,
                    buf, cb, checkVersion, out results);

                Debug.Trace("OutOfProcSessionStateStoreMakeRequest", "MakeRequest returned: " +
                            "hr=" + hr +
                            " socket=" + (IntPtr)results.socket +
                            " httpstatus=" + results.httpStatus +
                            " timeout=" + results.timeout +
                            " contentlength=" + results.contentLength +
                            " uri=" + (IntPtr)results.content +
                            " lockCookie=" + results.lockCookie +
                            " lockDate=" + string.Format("{0:x}", results.lockDate) +
                            " lockAge=" + results.lockAge +
                            " stateServerMajVer=" + results.stateServerMajVer +
                            " actionFlags=" + results.actionFlags);

                if (conn != null)
                {
                    if (results.socket == INVALID_SOCKET)
                    {
                        conn.Detach();
                        conn = null;
                    }
                    else if (results.socket != socketHandle.Handle)
                    {
                        // The original socket is no good.  We've got a new one.
                        // Pleae note that EnsureConnected has closed the bad
                        // one already.
                        conn._socketHandle = new HandleRef(this, results.socket);
                    }
                }
                else if (results.socket != INVALID_SOCKET)
                {
                    conn = new OutOfProcConnection(results.socket);
                }

                if (conn != null)
                {
                    _partitionInfo.StoreResource(conn);
                }
            }
            catch {
                // We just need to dispose the connection if anything bad happened
                if (conn != null)
                {
                    conn.Dispose();
                }

                throw;
            }

            if (hr != 0)
            {
                HttpException e = CreateConnectionException(_partitionInfo.Server, _partitionInfo.Port, hr);

                string phase = null;

                switch (results.lastPhase)
                {
                case (int)UnsafeNativeMethods.SessionNDMakeRequestPhase.Initialization:
                    phase = SR.GetString(SR.State_Server_detailed_error_phase0);
                    break;

                case (int)UnsafeNativeMethods.SessionNDMakeRequestPhase.Connecting:
                    phase = SR.GetString(SR.State_Server_detailed_error_phase1);
                    break;

                case (int)UnsafeNativeMethods.SessionNDMakeRequestPhase.SendingRequest:
                    phase = SR.GetString(SR.State_Server_detailed_error_phase2);
                    break;

                case (int)UnsafeNativeMethods.SessionNDMakeRequestPhase.ReadingResponse:
                    phase = SR.GetString(SR.State_Server_detailed_error_phase3);
                    break;

                default:
                    Debug.Assert(false, "Unknown results.lastPhase: " + results.lastPhase);
                    break;
                }

                WebBaseEvent.RaiseSystemEvent(SR.GetString(SR.State_Server_detailed_error,
                                                           phase,
                                                           "0x" + hr.ToString("X08", CultureInfo.InvariantCulture),
                                                           cb.ToString(CultureInfo.InvariantCulture)),
                                              this, WebEventCodes.WebErrorOtherError, WebEventCodes.StateServerConnectionError, e);

                throw e;
            }

            if (results.httpStatus == 400)
            {
                if (s_usePartition)
                {
                    throw new HttpException(
                              SR.GetString(SR.Bad_state_server_request_partition_resolver,
                                           s_configPartitionResolverType, _partitionInfo.Server, _partitionInfo.Port.ToString(CultureInfo.InvariantCulture)));
                }
                else
                {
                    throw new HttpException(
                              SR.GetString(SR.Bad_state_server_request));
                }
            }

            if (checkVersion)
            {
                _partitionInfo.StateServerVersion = results.stateServerMajVer;
                if (_partitionInfo.StateServerVersion < WHIDBEY_MAJOR_VERSION)
                {
                    // We won't work with versions lower than Whidbey
                    if (s_usePartition)
                    {
                        throw new HttpException(
                                  SR.GetString(SR.Need_v2_State_Server_partition_resolver,
                                               s_configPartitionResolverType, _partitionInfo.Server, _partitionInfo.Port.ToString(CultureInfo.InvariantCulture)));
                    }
                    else
                    {
                        throw new HttpException(
                                  SR.GetString(SR.Need_v2_State_Server));
                    }
                }
            }
        }
コード例 #9
0
        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();
                }
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        private void MakeRequest(System.Web.UnsafeNativeMethods.StateProtocolVerb verb, string id, System.Web.UnsafeNativeMethods.StateProtocolExclusive exclusiveAccess, int extraFlags, int timeout, int lockCookie, byte[] buf, int cb, int networkTimeout, out System.Web.UnsafeNativeMethods.SessionNDMakeRequestResults results)
        {
            int num;
            OutOfProcConnection o = null;
            bool checkVersion     = false;

            SessionIDManager.CheckIdLength(id, true);
            if (this._partitionInfo == null)
            {
                this._partitionInfo = (StateServerPartitionInfo)s_partitionManager.GetPartition(this._partitionResolver, id);
                if (this._partitionInfo == null)
                {
                    throw new HttpException(System.Web.SR.GetString("Bad_partition_resolver_connection_string", new object[] { "PartitionManager" }));
                }
            }
            try
            {
                HandleRef ref2;
                o = (OutOfProcConnection)this._partitionInfo.RetrieveResource();
                if (o != null)
                {
                    ref2 = new HandleRef(this, o._socketHandle.Handle);
                }
                else
                {
                    ref2 = new HandleRef(this, INVALID_SOCKET);
                }
                if (this._partitionInfo.StateServerVersion == -1)
                {
                    checkVersion = true;
                }
                string uri = HttpUtility.UrlEncode(s_uribase + id);
                num = System.Web.UnsafeNativeMethods.SessionNDMakeRequest(ref2, this._partitionInfo.Server, this._partitionInfo.Port, networkTimeout, verb, uri, exclusiveAccess, extraFlags, timeout, lockCookie, buf, cb, checkVersion, out results);
                if (o != null)
                {
                    if (results.socket == INVALID_SOCKET)
                    {
                        o.Detach();
                        o = null;
                    }
                    else if (results.socket != ref2.Handle)
                    {
                        o._socketHandle = new HandleRef(this, results.socket);
                    }
                }
                else if (results.socket != INVALID_SOCKET)
                {
                    o = new OutOfProcConnection(results.socket);
                }
                if (o != null)
                {
                    this._partitionInfo.StoreResource(o);
                }
            }
            catch
            {
                if (o != null)
                {
                    o.Dispose();
                }
                throw;
            }
            if (num == 0)
            {
                if (results.httpStatus == 400)
                {
                    if (s_usePartition)
                    {
                        throw new HttpException(System.Web.SR.GetString("Bad_state_server_request_partition_resolver", new object[] { s_configPartitionResolverType, this._partitionInfo.Server, this._partitionInfo.Port.ToString(CultureInfo.InvariantCulture) }));
                    }
                    throw new HttpException(System.Web.SR.GetString("Bad_state_server_request"));
                }
                if (checkVersion)
                {
                    this._partitionInfo.StateServerVersion = results.stateServerMajVer;
                    if (this._partitionInfo.StateServerVersion < WHIDBEY_MAJOR_VERSION)
                    {
                        if (s_usePartition)
                        {
                            throw new HttpException(System.Web.SR.GetString("Need_v2_State_Server_partition_resolver", new object[] { s_configPartitionResolverType, this._partitionInfo.Server, this._partitionInfo.Port.ToString(CultureInfo.InvariantCulture) }));
                        }
                        throw new HttpException(System.Web.SR.GetString("Need_v2_State_Server"));
                    }
                }
            }
            else
            {
                HttpException exception = CreateConnectionException(this._partitionInfo.Server, this._partitionInfo.Port, num);
                string        str2      = null;
                switch (results.lastPhase)
                {
                case 0:
                    str2 = System.Web.SR.GetString("State_Server_detailed_error_phase0");
                    break;

                case 1:
                    str2 = System.Web.SR.GetString("State_Server_detailed_error_phase1");
                    break;

                case 2:
                    str2 = System.Web.SR.GetString("State_Server_detailed_error_phase2");
                    break;

                case 3:
                    str2 = System.Web.SR.GetString("State_Server_detailed_error_phase3");
                    break;
                }
                WebBaseEvent.RaiseSystemEvent(System.Web.SR.GetString("State_Server_detailed_error", new object[] { str2, "0x" + num.ToString("X08", CultureInfo.InvariantCulture), cb.ToString(CultureInfo.InvariantCulture) }), this, 0xbc1, 0xc360, exception);
                throw exception;
            }
        }
コード例 #12
0
        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));
        }
コード例 #13
0
        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);
                }
            }
        }