Merge pull request #3968 from BrzVlad/fix-monitor-exception
[mono.git] / mono / metadata / property-bag.c
1
2 /*
3  * property-bag.c: Linearizable property bag.
4  *
5  * Authors:
6  *   Rodrigo Kumpera (kumpera@gmail.com)
7  *
8  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
9  */
10 #include <mono/metadata/property-bag.h>
11 #include <mono/utils/atomic.h>
12 #include <mono/utils/mono-membar.h>
13
14 void*
15 mono_property_bag_get (MonoPropertyBag *bag, int tag)
16 {
17         MonoPropertyBagItem *item;
18         
19         for (item = bag->head; item && item->tag <= tag; item = item->next) {
20                 if (item->tag == tag)
21                         return item;
22         }
23         return NULL;
24 }
25
26 void*
27 mono_property_bag_add (MonoPropertyBag *bag, void *value)
28 {
29         MonoPropertyBagItem *cur, **prev, *item = value;
30         int tag = item->tag;
31         mono_memory_barrier (); //publish the values in value
32
33 retry:
34         prev = &bag->head;
35         while (1) {
36                 cur = *prev;
37                 if (!cur || cur->tag > tag) {
38                         item->next = cur;
39                         if (InterlockedCompareExchangePointer ((void*)prev, item, cur) == cur)
40                                 return item;
41                         goto retry;
42                 } else if (cur->tag == tag) {
43                         return cur;
44                 } else {
45                         prev = &cur->next;
46                 }
47         }
48         return value;
49 }