Merge pull request #2964 from ludovic-henry/sgen-monocontext
[mono.git] / mcs / class / referencesource / System.Web / Util / SafeBitVector32.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="SimpleBitVector32.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 //------------------------------------------------------------------------------
6
7 using System;
8 using System.Threading;
9
10 namespace System.Web.Util {
11     //
12     // This is a multithreadsafe version of System.Collections.Specialized.BitVector32.
13     //
14     [Serializable]
15     internal struct SafeBitVector32 {
16         private volatile int _data;
17     
18         internal SafeBitVector32(int data) {
19             this._data = data;
20         }
21
22         internal bool this[int bit] {
23             get {
24                 int data = _data;
25                 return (data & bit) == bit;
26             }
27             set {
28                 for (;;) {
29                     int oldData = _data;
30                     int newData;
31                     if (value) {
32                         newData = oldData | bit;
33                     }
34                     else {
35                         newData = oldData & ~bit;
36                     }
37
38 #pragma warning disable 0420
39                     int result = Interlocked.CompareExchange(ref _data, newData, oldData);
40 #pragma warning restore 0420
41
42                     if (result == oldData) {
43                         break;
44                     }
45                 }
46             }
47         }
48
49
50         internal bool ChangeValue(int bit, bool value) {
51             for (;;) {
52                 int oldData = _data;
53                 int newData;
54                 if (value) {
55                     newData = oldData | bit;
56                 }
57                 else {
58                     newData = oldData & ~bit;
59                 }
60
61                 if (oldData == newData) {
62                     return false;
63                 }
64
65 #pragma warning disable 0420
66                 int result = Interlocked.CompareExchange(ref _data, newData, oldData);
67 #pragma warning restore 0420
68
69                 if (result == oldData) {
70                     return true;
71                 }
72             }
73         }
74     }
75 }
76