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.
34 using System.Threading;
35 using System.Web.Caching;
37 namespace System.Web.SessionState {
38 class LockableStateServerItem
40 public StateServerItem item;
41 public ReaderWriterLock rwlock;
43 public LockableStateServerItem (StateServerItem item)
46 this.rwlock = new ReaderWriterLock ();
50 internal class RemoteStateServer : MarshalByRefObject {
51 const Int32 lockAcquireTimeout = 30000;
54 internal RemoteStateServer ()
59 void Insert (string id, LockableStateServerItem item)
61 cache.Insert (id, item, null, Cache.NoAbsoluteExpiration, new TimeSpan (0, item.item.Timeout, 0));
64 LockableStateServerItem Retrieve (string id)
66 return cache [id] as LockableStateServerItem;
69 internal void CreateUninitializedItem (string id, int timeout)
71 StateServerItem item = new StateServerItem (timeout);
72 item.Action = SessionStateActions.InitializeItem;
73 LockableStateServerItem cacheItem = new LockableStateServerItem (item);
74 Insert (id, cacheItem);
77 internal StateServerItem GetItem (string id,
81 out SessionStateActions actions,
85 lockAge = TimeSpan.MinValue;
86 lockId = Int32.MinValue;
87 actions = SessionStateActions.None;
89 LockableStateServerItem item = Retrieve (id);
90 if (item == null || item.item.IsAbandoned ())
94 item.rwlock.AcquireReaderLock (lockAcquireTimeout);
95 if (item.item.Locked) {
97 lockAge = DateTime.UtcNow.Subtract (item.item.LockedTime);
98 lockId = item.item.LockId;
102 item.rwlock.ReleaseReaderLock ();
104 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
105 item.item.Locked = true;
106 item.item.LockedTime = DateTime.UtcNow;
108 lockId = item.item.LockId;
113 if (item.rwlock.IsReaderLockHeld)
114 item.rwlock.ReleaseReaderLock ();
116 if (item.rwlock.IsWriterLockHeld)
117 item.rwlock.ReleaseWriterLock ();
120 actions = item.item.Action;
124 internal void Remove (string id, object lockid)
129 internal void ResetItemTimeout (string id)
131 LockableStateServerItem item = Retrieve (id);
137 internal void ReleaseItemExclusive (string id, object lockId)
139 LockableStateServerItem item = Retrieve (id);
140 if (item == null || item.item.LockId != (Int32)lockId)
144 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
145 item.item.Locked = false;
149 if (item.rwlock.IsWriterLockHeld)
150 item.rwlock.ReleaseWriterLock ();
154 internal void SetAndReleaseItemExclusive (string id, byte [] collection_data, byte [] sobjs_data,
155 object lockId, int timeout, bool newItem)
157 LockableStateServerItem item = Retrieve (id);
160 if (newItem || item == null) {
161 item = new LockableStateServerItem (new StateServerItem (collection_data, sobjs_data, timeout));
162 item.item.LockId = (Int32)lockId;
165 if (item.item.LockId != (Int32)lockId)
171 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
172 item.item.Locked = false;
174 item.item.CollectionData = collection_data;
175 item.item.StaticObjectsData = sobjs_data;
181 if (item.rwlock.IsWriterLockHeld)
182 item.rwlock.ReleaseWriterLock ();
186 public override object InitializeLifetimeService ()
188 return null; // just in case...