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,
84 Console.WriteLine ("RemoteStateServer.GetItem");
85 Console.WriteLine ("\tid == {0}", id);
87 lockAge = TimeSpan.MinValue;
88 lockId = Int32.MinValue;
89 actions = SessionStateActions.None;
91 LockableStateServerItem item = Retrieve (id);
92 if (item == null || item.item.IsAbandoned ()) {
93 Console.WriteLine ("\tNo item for that id (abandoned == {0})", item != null ? item.item.IsAbandoned() : false);
98 Console.WriteLine ("\tacquiring reader lock");
99 item.rwlock.AcquireReaderLock (lockAcquireTimeout);
100 if (item.item.Locked) {
101 Console.WriteLine ("\titem is locked");
103 lockAge = DateTime.UtcNow.Subtract (item.item.LockedTime);
104 lockId = item.item.LockId;
107 Console.WriteLine ("\teleasing reader lock");
108 item.rwlock.ReleaseReaderLock ();
110 Console.WriteLine ("\tacquiring writer lock");
111 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
112 Console.WriteLine ("\tlocking the item");
113 item.item.Locked = true;
114 item.item.LockedTime = DateTime.UtcNow;
116 Console.WriteLine ("\tnew lock id == {0}", item.item.LockId);
117 lockId = item.item.LockId;
122 if (item.rwlock.IsReaderLockHeld) {
123 Console.WriteLine ("\treleasing reader lock [finally]");
124 item.rwlock.ReleaseReaderLock ();
126 if (item.rwlock.IsWriterLockHeld) {
127 Console.WriteLine ("\treleasing writer lock [finally]");
128 item.rwlock.ReleaseWriterLock ();
132 Console.WriteLine ("\treturning an item");
133 actions = item.item.Action;
137 internal void Remove (string id, object lockid)
142 internal void ResetItemTimeout (string id)
144 LockableStateServerItem item = Retrieve (id);
150 internal void ReleaseItemExclusive (string id, object lockId)
152 LockableStateServerItem item = Retrieve (id);
153 if (item == null || item.item.LockId != (Int32)lockId)
157 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
158 item.item.Locked = false;
162 if (item.rwlock.IsWriterLockHeld)
163 item.rwlock.ReleaseWriterLock ();
167 internal void SetAndReleaseItemExclusive (string id, byte [] collection_data, byte [] sobjs_data,
168 object lockId, int timeout, bool newItem)
170 Console.WriteLine ("RemoteStateServer.SetAndReleaseItemExclusive");
171 Console.WriteLine ("\tid == {0}", id);
172 LockableStateServerItem item = Retrieve (id);
175 if (newItem || item == null) {
176 Console.WriteLine ("\tnew item");
177 item = new LockableStateServerItem (new StateServerItem (collection_data, sobjs_data, timeout));
178 item.item.LockId = (Int32)lockId;
181 if (item.item.LockId != (Int32)lockId) {
182 Console.WriteLine ("\tLockId mismatch ({0} != {1})", item.item.LockId, lockId);
185 Console.WriteLine ("\tremoving from cache");
190 Console.WriteLine ("\tacquiring writer lock");
191 item.rwlock.AcquireWriterLock (lockAcquireTimeout);
192 item.item.Locked = false;
194 Console.WriteLine ("\tnot fresh = updating data");
195 item.item.CollectionData = collection_data;
196 item.item.StaticObjectsData = sobjs_data;
198 Console.WriteLine ("\tInserting in cache");
203 if (item.rwlock.IsWriterLockHeld) {
204 Console.WriteLine ("\treleasing writer lock [finally]");
205 item.rwlock.ReleaseWriterLock ();
210 public override object InitializeLifetimeService ()
212 return null; // just in case...