/*public*/ void IStateClientManager.Set(String id, SessionStateItem item, bool inStorage) { byte [] buf; int length; MemoryStream s; try { s = new MemoryStream(ITEM_SHORT_LENGTH); Serialize(item, s); buf = s.GetBuffer(); length = (int)s.Length; s.Close(); } catch { if (inStorage) { ((IStateClientManager)this).ReleaseExclusive(id, item.lockCookie); } throw; } #if SYNCHRONOUS SetAsyncWorker(id, item, buf, length, inStorage); #else if (inStorage) { SetAsync(id, item, buf, length, inStorage); } else { SetAsyncWorker(id, item, buf, length, inStorage); } #endif }
static protected void Serialize(SessionStateItem item, Stream stream) { bool hasDict; bool hasStaticObjects; BinaryWriter writer = new BinaryWriter(stream); writer.Write(item.timeout); writer.Write(item.isCookieless); hasDict = item.dict != null; writer.Write(hasDict); hasStaticObjects = item.staticObjects != null; writer.Write(hasStaticObjects); if (hasDict) { item.dict.Serialize(writer); } if (hasStaticObjects) { item.staticObjects.Serialize(writer); } // Prevent truncation of the stream writer.Write(unchecked ((byte)0xff)); }
// Called by IStateClientManager::Set protected void SetAsync(String id, SessionStateItem item, byte[] buf, int length, bool inStorage) { AsyncWorkItem asyncWorkItem = new AsyncWorkItem(this, id, item, buf, length, inStorage, 0); WorkItem.PostInternal(new WorkItemCallback(asyncWorkItem.SetAsyncCallback)); }
internal AsyncWorkItem(StateClientManager manager, String id, SessionStateItem item, byte[] buf, int length, bool inStorage, int lockCookie) { _manager = manager; _id = id; _item = item; _buf = buf; _length = length; _inStorage = inStorage; _lockCookie = lockCookie; }
protected override void SetAsyncWorker(String id, SessionStateItem item, byte[] buf, int length, bool inStorage) { UnsafeNativeMethods.SessionNDMakeRequestResults results; Debug.Trace("SessionStateClientManager", "Calling Set, id=" + id + " dict=" + item.dict + " timeout=" + item.timeout); MakeRequest(UnsafeNativeMethods.StateProtocolVerb.PUT, id, UnsafeNativeMethods.StateProtocolExclusive.NONE, item.timeout, item.lockCookie, buf, length, s_networkTimeout, out results); }
static protected SessionStateItem Deserialize( Stream stream, int lockCookie) { SessionStateItem item; int timeout; bool isCookieless; SessionDictionary dict; bool hasDict; bool hasStaticObjects; HttpStaticObjectsCollection col; Byte eof; BinaryReader reader = new BinaryReader(stream); timeout = reader.ReadInt32(); isCookieless = reader.ReadBoolean(); hasDict = reader.ReadBoolean(); hasStaticObjects = reader.ReadBoolean(); if (hasDict) { dict = SessionDictionary.Deserialize(reader); } else { dict = null; } if (hasStaticObjects) { col = HttpStaticObjectsCollection.Deserialize(reader); } else { col = null; } eof = reader.ReadByte(); Debug.Assert(eof == 0xff); item = new SessionStateItem( dict, col, timeout, isCookieless, (int)stream.Position, false, TimeSpan.Zero, lockCookie); return(item); }
// Called by IStateClientManager::BeginGet protected IAsyncResult BeginGetSync(String id, AsyncCallback cb, Object state) { SessionStateItem item = Get(id); return(new HttpAsyncResult(cb, state, true, item, null)); }
// Callback func for the worker thread from SetAsync protected virtual void SetAsyncWorker(String id, SessionStateItem item, byte[] buf, int lenght, bool inStorage) { }
/*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); } }
protected override void SetAsyncWorker(String id, SessionStateItem item, byte[] buf, int length, bool inStorage) { SqlCommand cmd; Debug.Trace("SessionStateClientManager", "Calling Sql Set, id=" + id); bool usePooling = true; SqlStateConnection conn = GetConnection(ref usePooling); try { if (inStorage) { Debug.Assert(item.streamLength > 0, "item.streamLength > 0"); if (length <= ITEM_SHORT_LENGTH) { if (item.streamLength <= ITEM_SHORT_LENGTH) { cmd = conn._cmdTempUpdateShort; } else { cmd = conn._cmdTempUpdateShortNullLong; } } else { if (item.streamLength <= ITEM_SHORT_LENGTH) { cmd = conn._cmdTempUpdateLongNullShort; } else { cmd = conn._cmdTempUpdateLong; } } } else { if (length <= ITEM_SHORT_LENGTH) { cmd = conn._cmdTempInsertShort; } else { cmd = conn._cmdTempInsertLong; } } cmd.Parameters[0].Value = id + s_appSuffix; cmd.Parameters[1].Size = length; cmd.Parameters[1].Value = buf; cmd.Parameters[2].Value = item.timeout; if (inStorage) { cmd.Parameters[3].Value = item.lockCookie; } try { cmd.ExecuteNonQuery(); } catch (Exception e) { SqlException sqlExpt = e as SqlException; if (sqlExpt != null && sqlExpt.Number == SQL_ERROR_PRIMARY_KEY_VIOLATION && !inStorage) { Debug.Trace("SessionStateClientSet", "Insert failed because of primary key violation; just leave gracefully; id=" + id); // It's possible that two threads (from the same session) are creating the session // state, both failed to get it first, and now both tried to insert it. // One thread may lose with a Primary Key Violation error. If so, that thread will // just lose and exit gracefully. } else { throw new HttpException( HttpRuntime.FormatResourceString(SR.Cant_connect_sql_session_database), e); } } } catch { conn.Dispose(); throw; } ReuseConnection(ref conn, usePooling); }
internal SessionStateItem DoGet(String id, UnsafeNativeMethods.StateProtocolExclusive exclusiveAccess) { SessionStateItem item = null; MemoryStream stream; int contentLength; TimeSpan lockAge; UnsafeNativeMethods.SessionNDMakeRequestResults results; MakeRequest(UnsafeNativeMethods.StateProtocolVerb.GET, id, exclusiveAccess, 0, 0, null, 0, s_networkTimeout, out results); switch (results.httpStatus) { case 200: /* item found, deserialize it */ contentLength = results.contentLength; if (contentLength > 0) { if (_bufGet == null || _bufGet.Length < contentLength) { _bufGet = new byte[contentLength]; } UnsafeNativeMethods.SessionNDGetBody(new HandleRef(this, results.content), _bufGet, contentLength); stream = new MemoryStream(_bufGet); item = (SessionStateItem)Deserialize(stream, results.lockCookie); stream.Close(); } break; case 423: /* state locked, return lock information */ if (0 <= results.lockAge) { if (results.lockAge < Sec.ONE_YEAR) { lockAge = new TimeSpan(0, 0, results.lockAge); } else { lockAge = TimeSpan.Zero; } } else { DateTime now = DateTime.Now; if (0 < results.lockDate && results.lockDate < now.Ticks) { lockAge = now - new DateTime(results.lockDate); } else { lockAge = TimeSpan.Zero; } } item = new SessionStateItem( null, null, 0, false, 0, true, lockAge, results.lockCookie); break; } return(item); }