SessionStateStoreData GetItemInternal (HttpContext context,
string id,
out bool locked,
out TimeSpan lockAge,
out object lockId,
out SessionStateActions actions,
bool exclusive)
{
locked = false;
lockAge = TimeSpan.MinValue;
lockId = Int32.MinValue;
actions = SessionStateActions.None;
if (id == null)
return null;
Cache cache = HttpRuntime.InternalCache;
string CacheId = CachePrefix + id;
InProcSessionItem item = cache [CacheId] as InProcSessionItem;
if (item == null)
return null;
bool readLocked = false, writeLocked = false;
try {
if (item.rwlock.TryEnterUpgradeableReadLock (lockAcquireTimeout))
readLocked = true;
else
throw new ApplicationException ("Failed to acquire lock");
if (item.locked) {
locked = true;
lockAge = DateTime.UtcNow.Subtract (item.lockedTime);
lockId = item.lockId;
return null;
}
if (exclusive) {
if (item.rwlock.TryEnterWriteLock (lockAcquireTimeout))
writeLocked = true;
else
throw new ApplicationException ("Failed to acquire lock");
item.locked = true;
item.lockedTime = DateTime.UtcNow;
item.lockId++;
lockId = item.lockId;
}
if (item.items == null) {
actions = SessionStateActions.InitializeItem;
item.items = new SessionStateItemCollection ();
}
if (item.staticItems == null)
item.staticItems = staticObjects;
return new SessionStateStoreData (item.items,
item.staticItems,
item.timeout);
} catch {
// we want such errors to be passed to the application.
throw;
} finally {
if (writeLocked)
item.rwlock.ExitWriteLock ();
if (readLocked)
item.rwlock.ExitUpgradeableReadLock ();
}
}