Only set the attached flag when a client attaches (#3490)
[mono.git] / mono / metadata / reflection-cache.h
1 /* 
2  * Copyright 2016 Microsoft
3  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
4  */
5 #ifndef __MONO_METADATA_REFLECTION_CACHE_H__
6 #define __MONO_METADATA_REFLECTION_CACHE_H__
7
8 #include <glib.h>
9 #include <mono/metadata/domain-internals.h>
10 #include <mono/metadata/mono-hash.h>
11 #include <mono/metadata/mempool.h>
12
13 /*
14  * We need to return always the same object for MethodInfo, FieldInfo etc..
15  * but we need to consider the reflected type.
16  * type uses a different hash, since it uses custom hash/equal functions.
17  */
18
19 typedef struct {
20         gpointer item;
21         MonoClass *refclass;
22 } ReflectedEntry;
23
24 gboolean
25 reflected_equal (gconstpointer a, gconstpointer b);
26
27 guint
28 reflected_hash (gconstpointer a);
29
30 #ifdef HAVE_BOEHM_GC
31 /* ReflectedEntry doesn't need to be GC tracked */
32 #define ALLOC_REFENTRY g_new0 (ReflectedEntry, 1)
33 #define FREE_REFENTRY(entry) g_free ((entry))
34 #define REFENTRY_REQUIRES_CLEANUP
35 #else
36 #define ALLOC_REFENTRY (ReflectedEntry *)mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
37 /* FIXME: */
38 #define FREE_REFENTRY(entry)
39 #endif
40
41
42 #define CACHE_OBJECT(t,p,o,k)   \
43         do {    \
44                 t _obj; \
45         ReflectedEntry pe; \
46         pe.item = (p); \
47         pe.refclass = (k); \
48         mono_domain_lock (domain); \
49                 if (!domain->refobject_hash)    \
50                         domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");  \
51         _obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &pe); \
52         if (!_obj) { \
53                     ReflectedEntry *e = ALLOC_REFENTRY;         \
54                     e->item = (p);      \
55                     e->refclass = (k);  \
56                     mono_g_hash_table_insert (domain->refobject_hash, e,o);     \
57             _obj = o; \
58         } \
59                 mono_domain_unlock (domain);    \
60         return _obj; \
61         } while (0)
62
63 #define CHECK_OBJECT(t,p,k)     \
64         do {    \
65                 t _obj; \
66                 ReflectedEntry e;       \
67                 e.item = (p);   \
68                 e.refclass = (k);       \
69                 mono_domain_lock (domain);      \
70                 if (!domain->refobject_hash)    \
71                         domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");  \
72                 if ((_obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &e))) {        \
73                         mono_domain_unlock (domain);    \
74                         return _obj;    \
75                 }       \
76         mono_domain_unlock (domain); \
77         } while (0)
78
79
80 #endif /*__MONO_METADATA_REFLECTION_CACHE_H__*/