private void ExtractValuesFromGetItemResult(GetItemResult result, out SessionStateStoreData rqItem,
                                             out bool locked, out TimeSpan lockAge, out object rqLockId, out SessionStateActions rqActionFlags)
 {
     rqItem        = result.Item;
     locked        = result.Locked;
     lockAge       = result.LockAge;
     rqLockId      = result.LockId;
     rqActionFlags = result.Actions;
 }
Beispiel #2
0
        private Task <GetItemResult> DoGetAsync(HttpContextBase context, string id, bool exclusive)
        {
            bool                locked;
            TimeSpan            lockAge;
            object              lockId;
            SessionStateActions actionFlags;

            var           item   = DoGet(context, id, exclusive, out locked, out lockAge, out lockId, out actionFlags);
            GetItemResult result = new GetItemResult(item, locked, lockAge, lockId, actionFlags);

            return(Task.FromResult <GetItemResult>(result));
        }
        private async Task LockSessionStateItemAsync()
        {
            Debug.Assert(_rqId != null, "_rqId != null");

            if (!_rqReadonly)
            {
                GetItemResult result = await _store.GetItemExclusiveAsync(_rqContext, _rqId, GetCancellationToken());

                SessionStateStoreData storedItem;
                bool     locked;
                TimeSpan lockAge;

                Debug.Assert(result != null, "Must succeed in retrieving item from the store through _rqId");
                ExtractValuesFromGetItemResult(result, out storedItem, out locked, out lockAge, out _rqLockId,
                                               out _rqActionFlags);
                Debug.Assert(storedItem != null, "Must succeed in locking session state item.");
            }
        }
        private async Task GetSessionStateItemAsync()
        {
            bool isCompleted = false;
            bool isQueued    = false;

            try
            {
                while (!isCompleted)
                {
                    isCompleted = true;
                    bool     locked  = false;
                    TimeSpan lockAge = default(TimeSpan);

                    Debug.Assert(_rqId != null, "_rqId != null");

                    if (_rqReadonly || AppSettings.AllowConcurrentRequestsPerSession)
                    {
                        GetItemResult result = await _store.GetItemAsync(_rqContext, _rqId, GetCancellationToken());

                        if (result != null)
                        {
                            ExtractValuesFromGetItemResult(result, out _rqItem, out locked, out lockAge, out _rqLockId,
                                                           out _rqActionFlags);
                        }
                    }
                    else
                    {
                        GetItemResult result = await _store.GetItemExclusiveAsync(_rqContext, _rqId, GetCancellationToken());

                        if (result != null)
                        {
                            ExtractValuesFromGetItemResult(result, out _rqItem, out locked, out lockAge, out _rqLockId,
                                                           out _rqActionFlags);
                        }

                        // WebForm and WebService Session Access Concurrency Issue
                        // If we have an expired session, we need to insert the state in the store here to
                        // ensure serialized access in case more than one entity requests it simultaneously.
                        // If the state has already been created before, CreateUninitializedSessionState is a no-op.
                        if (_rqItem == null && locked == false && _rqId != null)
                        {
                            if (!(ConfigCookieless == HttpCookieMode.UseUri && s_configRegenerateExpiredSessionId))
                            {
                                await _store.CreateUninitializedItemAsync(_rqContext, _rqId, s_timeout, GetCancellationToken());

                                GetItemResult getItemResult =
                                    await _store.GetItemExclusiveAsync(_rqContext, _rqId, GetCancellationToken());

                                if (getItemResult != null)
                                {
                                    ExtractValuesFromGetItemResult(getItemResult, out _rqItem, out locked, out lockAge,
                                                                   out _rqLockId, out _rqActionFlags);
                                }
                            }
                        }
                    }

                    // We didn't get it because it's locked....
                    if (_rqItem == null && locked)
                    {
                        if (!isQueued)
                        {
                            QueueRef();
                            isQueued = true;
                        }

                        if (lockAge >= _rqExecutionTimeout)
                        {
                            /* Release the lock on the item, which is held by another thread*/
                            await _store.ReleaseItemExclusiveAsync(_rqContext, _rqId, _rqLockId, GetCancellationToken());
                        }

                        isCompleted = false;
                    }

                    if (!isCompleted)
                    {
                        await Task.Delay(s_pollingTimespan);
                    }
                }
            }
            finally
            {
                if (isQueued)
                {
                    DequeRef();
                }
            }
        }