Handle multiple concurrent calls to BeginTryReceiveRequest
[mono.git] / mcs / class / System.ServiceModel / System.Collections.Generic / SynchronizedKeyedCollection.cs
1 //
2 // SynchronizedKeyedCollection.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.Runtime.InteropServices;
31 using System.ServiceModel.Channels;
32
33 namespace System.Collections.Generic
34 {
35         [ComVisibleAttribute (false)] 
36         public abstract class SynchronizedKeyedCollection<K, T>
37                 : SynchronizedCollection<T>
38         {
39                 Dictionary<K, T> dict;
40
41                 protected SynchronizedKeyedCollection ()
42                         : this (new object ())
43                 {
44                 }
45
46                 protected SynchronizedKeyedCollection (object syncRoot)
47                         : base (syncRoot)
48                 {
49                         dict = new Dictionary<K, T> ();
50                 }
51
52                 protected SynchronizedKeyedCollection (object syncRoot,
53                         IEqualityComparer<K> comparer)
54                         : base (syncRoot)
55                 {
56                         dict = new Dictionary<K, T> (comparer);
57                 }
58
59                 protected SynchronizedKeyedCollection (object syncRoot,
60                         IEqualityComparer<K> comparer, int capacity)
61                         : base (syncRoot)
62                 {
63                         dict = new Dictionary<K, T> (capacity, comparer);
64                 }
65
66                 // see bug #76417
67                 /*
68                 public T this [int index] {
69                         get { return base [index]; }
70                         set { base [index] = value; }
71                 }
72                 */
73
74                 public T this [K key] {
75                         get {
76                                 lock (SyncRoot) {
77                                         return dict [key];
78                                 }
79                         }
80                 }
81
82                 protected IDictionary<K, T> Dictionary {
83                         get { return dict; }
84                 }
85
86                 public bool Contains (K key)
87                 {
88                         lock (SyncRoot) {
89                                 return dict.ContainsKey (key);
90                         }
91                 }
92
93                 public bool Remove (K key)
94                 {
95                         lock (SyncRoot) {
96                                 return dict.Remove (key);
97                         }
98                 }
99
100                 protected void ChangeItemKey (T item, K newKey)
101                 {
102                         lock (SyncRoot) {
103                                 K old = GetKeyForItem (item);
104                                 dict [old] = default (T);
105                                 dict [newKey] = item;
106                         }
107                 }
108
109                 [MonoTODO ("This lock is not an atomic.")]
110                 protected override void ClearItems ()
111                 {
112                         base.ClearItems ();
113                         lock (SyncRoot) {
114                                 dict.Clear ();
115                         }
116                 }
117
118                 protected abstract K GetKeyForItem (T item);
119
120                 [MonoTODO ("This lock is not an atomic.")]
121                 protected override void InsertItem (int index, T item)
122                 {
123                         base.InsertItem (index, item);
124                         dict.Add (GetKeyForItem (item), item);
125                 }
126
127                 [MonoTODO ("This lock is not an atomic.")]
128                 protected override void RemoveItem (int index)
129                 {
130                         K key = GetKeyForItem (base [index]);
131                         base.RemoveItem (index);
132                         dict.Remove (key);
133                 }
134
135                 [MonoTODO ("This lock is not an atomic.")]
136                 protected override void SetItem (int index, T item)
137                 {
138                         base.SetItem (index, item);
139                         dict [GetKeyForItem (item)] = item;
140                 }
141         }
142 }