16
16
using Microsoft . Azure . Commands . Common . Authentication . Models ;
17
17
using Microsoft . Azure . Commands . Common . Authentication . Properties ;
18
18
using System ;
19
+ using System . Collections . Concurrent ;
19
20
using System . Collections . Generic ;
20
21
using System . Collections . Specialized ;
22
+ using System . Linq ;
21
23
using System . Net ;
22
24
using System . Net . Http ;
23
25
using System . Net . Http . Headers ;
26
+ using System . Threading ;
24
27
25
28
namespace Microsoft . Azure . Commands . Common . Authentication . Factories
26
29
{
@@ -30,12 +33,16 @@ public class ClientFactory : IClientFactory
30
33
31
34
private Dictionary < Type , IClientAction > _actions ;
32
35
private OrderedDictionary _handlers ;
36
+ private ReaderWriterLockSlim _actionsLock ;
37
+ private ReaderWriterLockSlim _handlersLock ;
33
38
34
39
public ClientFactory ( )
35
40
{
36
41
_actions = new Dictionary < Type , IClientAction > ( ) ;
42
+ _actionsLock = new ReaderWriterLockSlim ( ) ;
37
43
UserAgents = new HashSet < ProductInfoHeaderValue > ( ) ;
38
44
_handlers = new OrderedDictionary ( ) ;
45
+ _handlersLock = new ReaderWriterLockSlim ( ) ;
39
46
}
40
47
41
48
public virtual TClient CreateArmClient < TClient > ( AzureContext context , AzureEnvironment . Endpoint endpoint ) where TClient : Microsoft . Rest . ServiceClient < TClient >
@@ -108,8 +115,7 @@ public virtual TClient CreateClient<TClient>(AzureContext context, AzureEnvironm
108
115
public virtual TClient CreateClient < TClient > ( AzureSMProfile profile , AzureEnvironment . Endpoint endpoint ) where TClient : ServiceClient < TClient >
109
116
{
110
117
TClient client = CreateClient < TClient > ( profile . Context , endpoint ) ;
111
-
112
- foreach ( IClientAction action in _actions . Values )
118
+ foreach ( IClientAction action in GetActions ( ) )
113
119
{
114
120
action . Apply < TClient > ( client , profile , endpoint ) ;
115
121
}
@@ -154,7 +160,7 @@ public virtual TClient CreateClient<TClient>(AzureSMProfile profile, AzureSubscr
154
160
155
161
TClient client = CreateClient < TClient > ( context , endpoint ) ;
156
162
157
- foreach ( IClientAction action in _actions . Values )
163
+ foreach ( IClientAction action in GetActions ( ) )
158
164
{
159
165
action . Apply < TClient > ( client , profile , endpoint ) ;
160
166
}
@@ -242,34 +248,82 @@ public static HttpClientHandler CreateHttpClientHandler(string endpoint, ICreden
242
248
243
249
public void AddAction ( IClientAction action )
244
250
{
245
- if ( action != null )
251
+ _actionsLock . EnterWriteLock ( ) ;
252
+ try
253
+ {
254
+ if ( action != null )
255
+ {
256
+ action . ClientFactory = this ;
257
+ _actions [ action . GetType ( ) ] = action ;
258
+ }
259
+ }
260
+ finally
246
261
{
247
- action . ClientFactory = this ;
248
- _actions [ action . GetType ( ) ] = action ;
262
+ _actionsLock . ExitWriteLock ( ) ;
249
263
}
250
264
}
251
265
252
266
public void RemoveAction ( Type actionType )
253
267
{
254
- if ( _actions . ContainsKey ( actionType ) )
268
+ _actionsLock . EnterWriteLock ( ) ;
269
+ try
255
270
{
256
- _actions . Remove ( actionType ) ;
271
+ if ( _actions . ContainsKey ( actionType ) )
272
+ {
273
+ _actions . Remove ( actionType ) ;
274
+ }
275
+ }
276
+ finally
277
+ {
278
+ _actionsLock . ExitWriteLock ( ) ;
257
279
}
258
280
}
259
281
282
+ private IClientAction [ ] GetActions ( )
283
+ {
284
+ IClientAction [ ] result = null ;
285
+ _actionsLock . EnterReadLock ( ) ;
286
+ try
287
+ {
288
+ result = _actions . Values . ToArray ( ) ;
289
+ }
290
+ finally
291
+ {
292
+ _actionsLock . ExitReadLock ( ) ;
293
+ }
294
+
295
+ return result ;
296
+ }
297
+
260
298
public void AddHandler < T > ( T handler ) where T : DelegatingHandler , ICloneable
261
299
{
262
- if ( handler != null )
300
+ _handlersLock . EnterWriteLock ( ) ;
301
+ try
263
302
{
264
- _handlers [ handler . GetType ( ) ] = handler ;
303
+ if ( handler != null )
304
+ {
305
+ _handlers [ handler . GetType ( ) ] = handler ;
306
+ }
307
+ }
308
+ finally
309
+ {
310
+ _handlersLock . ExitWriteLock ( ) ;
265
311
}
266
312
}
267
313
268
314
public void RemoveHandler ( Type handlerType )
269
315
{
270
- if ( _handlers . Contains ( handlerType ) )
316
+ _handlersLock . EnterWriteLock ( ) ;
317
+ try
318
+ {
319
+ if ( _handlers . Contains ( handlerType ) )
320
+ {
321
+ _handlers . Remove ( handlerType ) ;
322
+ }
323
+ }
324
+ finally
271
325
{
272
- _handlers . Remove ( handlerType ) ;
326
+ _handlersLock . ExitWriteLock ( ) ;
273
327
}
274
328
}
275
329
@@ -296,24 +350,32 @@ public void AddUserAgent(string productName)
296
350
297
351
public DelegatingHandler [ ] GetCustomHandlers ( )
298
352
{
299
- List < DelegatingHandler > newHandlers = new List < DelegatingHandler > ( ) ;
300
- var enumerator = _handlers . GetEnumerator ( ) ;
301
- while ( enumerator . MoveNext ( ) )
353
+ _handlersLock . EnterReadLock ( ) ;
354
+ try
302
355
{
303
- var handler = enumerator . Value ;
304
- ICloneable cloneableHandler = handler as ICloneable ;
305
- if ( cloneableHandler != null )
356
+ List < DelegatingHandler > newHandlers = new List < DelegatingHandler > ( ) ;
357
+ var enumerator = _handlers . GetEnumerator ( ) ;
358
+ while ( enumerator . MoveNext ( ) )
306
359
{
307
- var newHandler = cloneableHandler . Clone ( ) ;
308
- DelegatingHandler convertedHandler = newHandler as DelegatingHandler ;
309
- if ( convertedHandler != null )
360
+ var handler = enumerator . Value ;
361
+ ICloneable cloneableHandler = handler as ICloneable ;
362
+ if ( cloneableHandler != null )
310
363
{
311
- newHandlers . Add ( convertedHandler ) ;
364
+ var newHandler = cloneableHandler . Clone ( ) ;
365
+ DelegatingHandler convertedHandler = newHandler as DelegatingHandler ;
366
+ if ( convertedHandler != null )
367
+ {
368
+ newHandlers . Add ( convertedHandler ) ;
369
+ }
312
370
}
313
371
}
314
- }
315
372
316
- return newHandlers . ToArray ( ) ;
373
+ return newHandlers . ToArray ( ) ;
374
+ }
375
+ finally
376
+ {
377
+ _handlersLock . ExitReadLock ( ) ;
378
+ }
317
379
}
318
380
}
319
381
}
0 commit comments