2 // System.Web.SessionState.RemoteStateServer
5 // Jackson Harper (jackson@ximian.com)
6 // Gonzalo Paniagua (gonzalo@ximian.com)
7 // Marek Habersack (grendello@gmail.com)
9 // (C) 2003-2006 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Threading;
34 using System.Web.Caching;
36 namespace System.Web.SessionState {
37 class LockableStateServerItem
39 public StateServerItem item;
40 public ReaderWriterLock rwlock;
42 public LockableStateServerItem (StateServerItem item)
45 this.rwlock = new ReaderWriterLock ();
49 internal class RemoteStateServer : MarshalByRefObject {
50 const Int32 lockAcquireTimeout = 30000;
53 internal RemoteStateServer ()
58 void Insert (string id, LockableStateServerItem item)
60 cache.Insert (id, item, null, Cache.NoAbsoluteExpiration, new TimeSpan (0, item.item.Timeout, 0));
63 LockableStateServerItem Retrieve (string id)
65 return cache [id] as LockableStateServerItem;
68 internal void CreateUninitializedItem (string id, int timeout)
70 StateServerItem item = new StateServerItem (timeout);
71 item.Action = SessionStateActions.InitializeItem;
72 LockableStateServerItem cacheItem = new LockableStateServerItem (item);
73 Insert (id, cacheItem);
76 internal StateServerItem GetItem (string id,
80 out SessionStateActions actions,
84 lockAge = TimeSpan.MinValue;
85 lockId = Int32.MinValue;
86 actions = SessionStateActions.None;
88 LockableStateServerItem item = Retrieve (id);
89 if (item == null || item.item.IsAbandoned ())
93 item.rwlock.AcquireReaderLock (lockAcquireTimeout);
94 if (item.item.Locked) {
96 lockAge = DateTime.UtcNow.Subtract (item.item.LockedTime);
97 lockId = item.item.LockId;
101 item.rwlock.ReleaseReaderLock ();
103 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
104 item.item.Locked = true;
105 item.item.LockedTime = DateTime.UtcNow;
107 lockId = item.item.LockId;
112 if (item.rwlock.IsReaderLockHeld)
113 item.rwlock.ReleaseReaderLock ();
115 if (item.rwlock.IsWriterLockHeld)
116 item.rwlock.ReleaseWriterLock ();
119 actions = item.item.Action;
123 internal void Remove (string id, object lockid)
128 internal void ResetItemTimeout (string id)
130 LockableStateServerItem item = Retrieve (id);
136 internal void ReleaseItemExclusive (string id, object lockId)
138 LockableStateServerItem item = Retrieve (id);
139 if (item == null || item.item.LockId != (Int32)lockId)
143 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
144 item.item.Locked = false;
148 if (item.rwlock.IsWriterLockHeld)
149 item.rwlock.ReleaseWriterLock ();
153 internal void SetAndReleaseItemExclusive (string id, byte [] collection_data, byte [] sobjs_data,
154 object lockId, int timeout, bool newItem)
156 LockableStateServerItem item = Retrieve (id);
159 if (newItem || item == null) {
160 item = new LockableStateServerItem (new StateServerItem (collection_data, sobjs_data, timeout));
161 item.item.LockId = (Int32)lockId;
164 if (item.item.LockId != (Int32)lockId)
170 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
171 item.item.Locked = false;
173 item.item.CollectionData = collection_data;
174 item.item.StaticObjectsData = sobjs_data;
180 if (item.rwlock.IsWriterLockHeld)
181 item.rwlock.ReleaseWriterLock ();
185 public override object InitializeLifetimeService ()
187 return null; // just in case...