Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@ -118,7 +118,7 @@ namespace System.Web.SessionState {
// with SQL provider
SessionIDManager.CheckIdLength(id, true /* throwOnFail */);
InProcSessionState state = (InProcSessionState) HttpRuntime.CacheInternal.Get(key);
InProcSessionState state = (InProcSessionState)HttpRuntime.Cache.InternalCache.Get(key);
if (state != null) {
bool lockedByOther; // True if the state is locked by another session
int initialFlags;
@ -224,7 +224,7 @@ namespace System.Web.SessionState {
SessionIDManager.CheckIdLength(id, true /* throwOnFail */);
InProcSessionState state = (InProcSessionState) HttpRuntime.CacheInternal.Get(key);
InProcSessionState state = (InProcSessionState)HttpRuntime.Cache.InternalCache.Get(key);
/* If the state isn't there, we probably took too long to run. */
if (state == null)
@ -250,7 +250,7 @@ namespace System.Web.SessionState {
bool newItem) {
string key = CreateSessionStateCacheKey(id);
bool doInsert = true;
CacheInternal cacheInternal = HttpRuntime.CacheInternal;
CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;
int lockCookieForInsert = NewLockCookie;
ISessionStateItemCollection items = null;
HttpStaticObjectsCollection staticObjects = null;
@ -312,7 +312,7 @@ namespace System.Web.SessionState {
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
where we do UtcInsert below because cacheInternal.Get above have just
updated its expiry time.
*/
stateCurrent._flags |= (int)SessionStateItemFlags.IgnoreCacheItemRemoved;
@ -346,9 +346,11 @@ namespace System.Web.SessionState {
}
finally {
// protected from ThreadAbortEx
cacheInternal.UtcInsert(
key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state._timeout, 0),
CacheItemPriority.NotRemovable, _callback);
cacheInternal.Insert(key, state, new CacheInsertOptions() {
SlidingExpiration = new TimeSpan(0, state._timeout, 0),
Priority = CacheItemPriority.NotRemovable,
OnRemovedCallback = _callback
});
PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL);
PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE);
@ -383,9 +385,11 @@ namespace System.Web.SessionState {
}
finally {
// protected from ThreadAbortEx
object existingEntry = HttpRuntime.CacheInternal.UtcAdd(
key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, timeout, 0),
CacheItemPriority.NotRemovable, _callback);
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);
@ -402,7 +406,7 @@ namespace System.Web.SessionState {
Debug.Assert(lockId != null, "lockId != null");
string key = CreateSessionStateCacheKey(id);
CacheInternal cacheInternal = HttpRuntime.CacheInternal;
CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;
int lockCookie = (int)lockId;
SessionIDManager.CheckIdLength(id, true /* throwOnFail */);
@ -438,7 +442,7 @@ namespace System.Web.SessionState {
string key = CreateSessionStateCacheKey(id);
SessionIDManager.CheckIdLength(id, true /* throwOnFail */);
HttpRuntime.CacheInternal.Get(key);
HttpRuntime.Cache.InternalCache.Get(key);
}
// Create a new SessionStateStoreData.

View File

@ -31,6 +31,8 @@ namespace System.Web.SessionState {
using System.Web.Hosting;
using System.Web.Management;
using Microsoft.Win32;
using System.Collections.Concurrent;
using System.Collections.Generic;
public delegate void SessionStateItemExpireCallback(
string id, SessionStateStoreData item);
@ -153,7 +155,8 @@ namespace System.Web.SessionState {
private static bool s_PollIntervalRegLookedUp = false;
private static object s_PollIntervalRegLock = new object();
private static ConcurrentDictionary<string, int> s_queuedRequestsNumPerSession = new ConcurrentDictionary<string, int>();
//
// Check if we can optmize for InProc case.
// Optimization details:
@ -962,7 +965,7 @@ namespace System.Web.SessionState {
Debug.Assert(storedItem != null, "Must succeed in locking session state item.");
}
}
bool GetSessionStateItem() {
bool isCompleted = true;
bool locked;
@ -1012,6 +1015,8 @@ namespace System.Web.SessionState {
}
void PollLockedSession() {
EnsureRequestTimeout();
if (_timerCallback == null) {
_timerCallback = new TimerCallback(this.PollLockedSessionCallback);
}
@ -1019,6 +1024,9 @@ namespace System.Web.SessionState {
if (_timer == null) {
_timerId++;
// Only call this method once when setting up timer to poll the session item.
// It should not be called in timer's callback
QueueRef();
#if DBG
if (!Debug.IsTagPresent("Timer") || Debug.IsTagEnabled("Timer"))
#endif
@ -1030,6 +1038,53 @@ namespace System.Web.SessionState {
}
}
private void EnsureRequestTimeout() {
// Request may be blocked in acquiring state longer than execution timeout.
// In that case, it will be timeout anyway after it gets the session item.
// So it makes sense to timeout it when waiting longer than executionTimeout.
if (_rqContext.HasTimeoutExpired) {
throw new HttpException(SR.GetString(SR.Request_timed_out));
}
}
private static bool IsRequestQueueEnabled {
get {
return (AppSettings.RequestQueueLimitPerSession != AppSettings.UnlimitedRequestsPerSession);
}
}
private void QueueRef() {
if (!IsRequestQueueEnabled || _rqId == null) {
return;
}
//
// Check the limit
int count = 0;
s_queuedRequestsNumPerSession.TryGetValue(_rqId, out count);
if (count >= AppSettings.RequestQueueLimitPerSession) {
throw new HttpException(SR.GetString(SR.Request_Queue_Limit_Per_Session_Exceeded));
}
//
// Add ref
s_queuedRequestsNumPerSession.AddOrUpdate(_rqId, 1, (key, value) => value + 1);
}
private void DequeRef() {
if (!IsRequestQueueEnabled || _rqId == null) {
return;
}
// Decrement the counter
if (s_queuedRequestsNumPerSession.AddOrUpdate(_rqId, 0, (key, value) => value - 1) == 0) {
//
// Remove the element when no more references
((ICollection<KeyValuePair<string, int>>)s_queuedRequestsNumPerSession).Remove(new KeyValuePair<string,int>(_rqId, 0));
}
}
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
private static void LookUpRegForPollInterval() {
lock (s_PollIntervalRegLock) {
@ -1167,6 +1222,8 @@ namespace System.Web.SessionState {
}
if (isCompleted || error != null) {
DequeRef();
_rqAr.Complete(false, null, error);
}
}

View File

@ -217,6 +217,7 @@ namespace System.Web.SessionState {
internal IntPtr _stateItem; // The pointer to the native memory that points to the psi
internal bool _locked;
internal DateTime _utcLockDate;
internal TimeSpan _slidingExpiration;
internal int _lockCookie;
internal int _extraFlags;
#pragma warning disable 0649
@ -228,6 +229,7 @@ namespace System.Web.SessionState {
IntPtr stateItem,
bool locked,
DateTime utcLockDate,
TimeSpan slidingExpiration,
int lockCookie,
int extraFlags) {
@ -235,6 +237,7 @@ namespace System.Web.SessionState {
_stateItem = stateItem;
_locked = locked;
_utcLockDate = utcLockDate;
_slidingExpiration = slidingExpiration;
_lockCookie = lockCookie;
_extraFlags = extraFlags;
}
@ -413,19 +416,17 @@ namespace System.Web.SessionState {
string exclusiveAccess;
string key;
CachedContent content;
CacheEntry entry;
int lockCookie;
int timeout;
key = CreateKey(request);
entry = (CacheEntry) HttpRuntime.CacheInternal.Get(key, CacheGetOptions.ReturnCacheEntry);
if (entry == null) {
content = (CachedContent) HttpRuntime.Cache.InternalCache.Get(key);
if (content == null) {
ReportNotFound(context);
return;
}
exclusiveAccess = request.Headers[StateHeaders.EXCLUSIVE_NAME];
content = (CachedContent) entry.Value;
content._spinLock.AcquireWriterLock();
try {
if (content._content == null) {
@ -483,7 +484,7 @@ namespace System.Web.SessionState {
response.AppendHeader(StateHeaders.LOCKCOOKIE_NAME_RAW, (content._lockCookie).ToString(CultureInfo.InvariantCulture));
}
timeout = (int) (entry.SlidingExpiration.Ticks / TimeSpan.TicksPerMinute);
timeout = (int)(content._slidingExpiration.Ticks / TimeSpan.TicksPerMinute);
response.AppendHeader(StateHeaders.TIMEOUT_NAME_RAW, (timeout).ToString(CultureInfo.InvariantCulture));
responseStream = response.OutputStream;
buf = content._content;
@ -520,7 +521,7 @@ namespace System.Web.SessionState {
int lockCookie;
int lockCookieNew = 1;
IntPtr stateItem;
CacheInternal cacheInternal = HttpRuntime.CacheInternal;
CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;
/* create the content */
requestStream = request.InputStream;
@ -561,8 +562,8 @@ namespace System.Web.SessionState {
/* lookup current value */
key = CreateKey(request);
CacheEntry entry = (CacheEntry) cacheInternal.Get(key, CacheGetOptions.ReturnCacheEntry);
if (entry != null) {
contentCurrent = (CachedContent) cacheInternal.Get(key);
if (contentCurrent != null) {
// DevDivBugs 146875: Expired Session State race condition
// We make sure we do not overwrite an already existing item with an uninitialized item.
if (((int)SessionStateItemFlags.Uninitialized & extraFlags) == 1) {
@ -573,7 +574,6 @@ namespace System.Web.SessionState {
return stateItem;
}
contentCurrent = (CachedContent) entry.Value;
contentCurrent._spinLock.AcquireWriterLock();
try {
if (contentCurrent._content == null) {
@ -587,7 +587,7 @@ namespace System.Web.SessionState {
return stateItem;
}
if (entry.SlidingExpiration == timeout && contentCurrent._content != null) {
if (contentCurrent._slidingExpiration == timeout && contentCurrent._content != null) {
/* delete the old state item */
IntPtr stateItemOld = contentCurrent._stateItem;
@ -619,12 +619,14 @@ namespace System.Web.SessionState {
}
}
content = new CachedContent(buf, stateItem, false, DateTime.MinValue, lockCookieNew, extraFlags);
cacheInternal.UtcInsert(
key, content, null, Cache.NoAbsoluteExpiration, timeout,
CacheItemPriority.NotRemovable, _removedHandler);
content = new CachedContent(buf, stateItem, false, DateTime.MinValue, timeout, lockCookieNew, extraFlags);
cacheInternal.Insert(key, content, new CacheInsertOptions() {
SlidingExpiration = timeout,
Priority = CacheItemPriority.NotRemovable,
OnRemovedCallback = _removedHandler
});
if (entry == null) {
if (contentCurrent == null) {
IncrementStateServiceCounter(StateServicePerfCounter.STATE_SERVICE_SESSIONS_TOTAL);
IncrementStateServiceCounter(StateServicePerfCounter.STATE_SERVICE_SESSIONS_ACTIVE);
}
@ -634,7 +636,7 @@ namespace System.Web.SessionState {
internal /*public*/ void DoDelete(HttpContext context) {
string key = CreateKey(context.Request);
CacheInternal cacheInternal = HttpRuntime.CacheInternal;
CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache;
CachedContent content = (CachedContent) cacheInternal.Get(key);
/* If the item isn't there, we probably took too long to run. */
@ -680,7 +682,7 @@ namespace System.Web.SessionState {
Object item;
key = CreateKey(context.Request);
item = HttpRuntime.CacheInternal.Get(key);
item = HttpRuntime.Cache.InternalCache.Get(key);
if (item == null) {
ReportNotFound(context);
}

View File

@ -23,7 +23,7 @@ namespace System.Web.SessionState {
class StateHttpWorkerRequest : HttpWorkerRequest {
/* long enough to hold the string representation of an IPv4 or IPv6 address; keep in [....] with tracker.cxx */
/* long enough to hold the string representation of an IPv4 or IPv6 address; keep in sync with tracker.cxx */
private const int ADDRESS_LENGTH_MAX = 64;
IntPtr _tracker;