/*public*/ void IStateClientManager.Set(String id, SessionStateItem item, bool inStorage) { string key = CreateSessionStateCacheKey(id); bool doInsert = true; CacheInternal cacheInternal = HttpRuntime.CacheInternal; Debug.Assert(!item.locked, "!item.locked"); Debug.Assert(item.lockAge == TimeSpan.Zero, "item.lockAge == TimeSpan.Zero"); if (inStorage) { Debug.Assert(item.lockCookie != 0, "item.lockCookie != 0"); InProcSessionState stateCurrent = (InProcSessionState)cacheInternal.Get(key); /* If the state isn't there, we probably took too long to run. */ if (stateCurrent == null) { return; } Debug.Trace("SessionStateClientSet", "state is inStorage; key = " + key); stateCurrent.spinLock.AcquireWriterLock(); try { /* Only set the state if we are the owner */ if (!stateCurrent.locked || stateCurrent.lockCookie != item.lockCookie) { Debug.Trace("SessionStateClientSet", "Leave because we're not the owner; key = " + key); return; } /* We can change the state in place if the timeout hasn't changed */ if (stateCurrent.timeout == item.timeout) { stateCurrent.Copy( item.dict, item.staticObjects, item.timeout, item.isCookieless, item.streamLength, false, DateTime.MinValue, item.lockCookie); doInsert = false; Debug.Trace("SessionStateClientSet", "Changing state inplace; key = " + key); } else { /* prevent overwriting when we drop the lock */ stateCurrent.lockCookie = 0; } } finally { stateCurrent.spinLock.ReleaseWriterLock(); } } else { PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE); TraceSessionStats(); } if (doInsert) { Debug.Trace("SessionStateClientSet", "Inserting state into Cache; key = " + key); InProcSessionState state = new InProcSessionState( item.dict, item.staticObjects, item.timeout, item.isCookieless, item.streamLength, false, DateTime.MinValue, 1); cacheInternal.UtcInsert( key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state.timeout, 0), CacheItemPriority.NotRemovable, s_callback); } }
public override void SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, object lockId, bool newItem) { string key = CreateSessionStateCacheKey(id); bool doInsert = true; CacheInternal cacheInternal = HttpRuntime.CacheInternal; int lockCookieForInsert = NewLockCookie; ISessionStateItemCollection items = null; HttpStaticObjectsCollection staticObjects = null; Debug.Assert(item.Items != null, "item.Items != null"); Debug.Assert(item.StaticObjects != null, "item.StaticObjects != null"); Debug.Assert(item.Timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES, "item.Timeout <= SessionStateModule.MAX_CACHE_BASED_TIMEOUT_MINUTES"); SessionIDManager.CheckIdLength(id, true /* throwOnFail */); if (item.Items.Count > 0) { items = item.Items; } if (!item.StaticObjects.NeverAccessed) { staticObjects = item.StaticObjects; } if (!newItem) { Debug.Assert(lockId != null, "lockId != null"); InProcSessionState stateCurrent = (InProcSessionState)cacheInternal.Get(key); int lockCookie = (int)lockId; /* If the state isn't there, we probably took too long to run. */ if (stateCurrent == null) { return; } Debug.Trace("SessionStateClientSet", "state is inStorage; key = " + key); Debug.Assert((stateCurrent._flags & (int)SessionStateItemFlags.Uninitialized) == 0, "Should never set an unitialized item; key = " + key); stateCurrent._spinLock.AcquireWriterLock(); try { /* Only set the state if we are the owner */ if (!stateCurrent._locked || stateCurrent._lockCookie != lockCookie) { Debug.Trace("SessionStateClientSet", "Leave because we're not the owner; key = " + key); return; } /* We can change the state in place if the timeout hasn't changed */ if (stateCurrent._timeout == item.Timeout) { stateCurrent.Copy( items, staticObjects, item.Timeout, false, DateTime.MinValue, lockCookie, stateCurrent._flags); // Don't need to insert into the Cache because an in-place copy is good enough. doInsert = false; Debug.Trace("SessionStateClientSet", "Changing state inplace; key = " + key); } else { /* We are going to insert a new item to replace the current one in Cache * because the expiry time has changed. * * Pleas note that an insert will cause the Session_End to be incorrectly raised. * * Please note that the item itself should not expire between now and * where we do UtcInsert below because CacheInternal.Get above have just * updated its expiry time. */ stateCurrent._flags |= (int)SessionStateItemFlags.IgnoreCacheItemRemoved; /* By setting _lockCookie to 0, we prevent an overwriting by ReleaseExclusive * when we drop the lock. * The scenario can happen if another request is polling and trying to prempt * the lock we have on the item. */ lockCookieForInsert = lockCookie; stateCurrent._lockCookie = 0; } } finally { stateCurrent._spinLock.ReleaseWriterLock(); } } if (doInsert) { Debug.Trace("SessionStateClientSet", "Inserting state into Cache; key = " + key); InProcSessionState state = new InProcSessionState( items, staticObjects, item.Timeout, false, DateTime.MinValue, lockCookieForInsert, 0); try { } finally { // protected from ThreadAbortEx cacheInternal.UtcInsert( key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state._timeout, 0), CacheItemPriority.NotRemovable, _callback); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE); TraceSessionStats(); } } }
public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { string key = this.CreateSessionStateCacheKey(id); bool flag = true; CacheInternal cacheInternal = HttpRuntime.CacheInternal; int newLockCookie = NewLockCookie; ISessionStateItemCollection sessionItems = null; HttpStaticObjectsCollection staticObjects = null; SessionIDManager.CheckIdLength(id, true); if (item.Items.Count > 0) { sessionItems = item.Items; } if (!item.StaticObjects.NeverAccessed) { staticObjects = item.StaticObjects; } if (!newItem) { InProcSessionState state = (InProcSessionState)cacheInternal.Get(key); int lockCookie = (int)lockId; if (state == null) { return; } state._spinLock.AcquireWriterLock(); try { if (!state._locked || (state._lockCookie != lockCookie)) { return; } if (state._timeout == item.Timeout) { state.Copy(sessionItems, staticObjects, item.Timeout, false, DateTime.MinValue, lockCookie, state._flags); flag = false; } else { state._flags |= 2; newLockCookie = lockCookie; state._lockCookie = 0; } } finally { state._spinLock.ReleaseWriterLock(); } } if (flag) { InProcSessionState state2 = new InProcSessionState(sessionItems, staticObjects, item.Timeout, false, DateTime.MinValue, newLockCookie, 0); try { } finally { cacheInternal.UtcInsert(key, state2, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state2._timeout, 0), CacheItemPriority.NotRemovable, this._callback); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE); } } }